其Moore状态图如图1所示。
S0/0S1/1S3/0S2/100110011
其中S0/0所代表的意思为现在是状态S0且输出为0,状态图最主要是将每个状态都给予一个编号,详细描述如下:
1) 在某状态时,列出所有的输出条件。
2) 在某状态时,当输入信号是什么则会跳至哪一个状态。
3) 在某状态时,当输入信号是什么则会维持原状态不变。
可以将图1的Moore状态机写成状态表如表1.
表1 Moore状态表
现态 |
次态 |
输出 |
||
输入 |
X=0 |
X=1 |
X=0 |
X=1 |
S0 |
S0 |
S1 |
0 |
0 |
S1 |
S1 |
S2 |
1 |
1 |
S2 |
S3 |
S0 |
0 |
0 |
S3 |
S0 |
S3 |
0 |
0 |
状态表主要描述它与状态图的关系,在设计状态机电路时,需要先定义状态机的变量,定义状态机的变量时使用枚举类型来定义,如下范例所示:
Type State is (S0,S1,S2,S3)
接下来,状态会被加以编码。其状态编码方式如下:
(1) 时序编码(Sequential)
将每个状态以二进制来做编码。
(2)格雷码(Gray)
也是将四个State以二进制来编码,不过不同的是每次编码只会差一个位,其主要缺点是状态改变必须依序改变,若状态不是依序,则Gray编码不适用。
(3) 独热码(One hot)
独热码状态编码的特色为每一个状态均有自己的触发器,所以若有N个状态就也存在有N个触发器,在任一时刻只会有一组状态编码,缺点是会产生较大的电路,但是相对的使用独热码状态编码对帧错相当有帮助。
三种格式之状态编码如表2所示。
状态 |
时序编码 |
Gray编码 |
One hot编码 |
S0 |
00 |
00 |
0001 |
S1 |
01 |
01 |
0010 |
S2 |
10 |
11 |
0100 |
S3 |
11 |
10 |
1000 |
从状态编码表可以看出时序编码和Gray编码均是用二个位来做编码,而以独热码作为编码方式则编码位增加至四个位,所以电路比其他两种编码方式都大一些。
所以可以使用属性来定义编码方式,若要编码成独热码编码,则可加上:
Type State is (S0,S1,S2,S3);
Attribute encoding of state;
Type is “0001 0010 0100 1000”;
在设计状态机时,通常使用进程语句来描述状态机,其中进程语句又可以分为三种方式:
n 一个进程
利用一个进程来描述状态的转换及输出信号的定义。
n 两个进程
一个为时序电路主要负责状态变量的更新,此进程为同步电路,而另一个进程语句主要是描述下次态变量和输出的更新。
n 三个进程
第一个进程主要负责状态变量的更新,第二个进程语句负责描述次态变量,而最后一个则是负责输出信号的更新。
有了以上的初步观念,可以设计图1四个状态的Moore状态机。
首先根据之前的状态表编写VHDL程序如下所示:
Library ieee;
Use ieee.std_logic_1164.all;
Use ieee.numeric_std.all;
Entity moore_fsm is
Port(
clk : in std_logic;
rstn : in std_logic;
x : in std_logic;
output : out std_logic
);
End moore_fsm;
Architecture rtl of moore_fsm is
Type state is (s0,s1,s2,s3); ---状态定义
Signal current_state : state; ---现态
Signal next_state : state; ---次态
Begin
Statefsm: process(rstn, x, current_state)
Begin
If rstn = ‘0’ then --异步reset
next_state <= s0;
output <= ‘0’;
else
case current_state is
when s0 =>
if x =’0’ then
next_state <= s0;
else
next_state <= s1;
end if;
output <= ‘0’;
when s1 =>
if x =’0’ then
next_state <= s1;
else
next_state <= s2;
end if;
output <= ‘1’;
when s2 =>
if x =’0’ then
next_state <= s3;
else
next_state <= s0;
end if;
output <= ‘0’;
when s3 =>
if x =’0’ then
next_state <= s0;
else
next_state <= s3;
end if;
output <= ‘0’;
end case;
end if;
end process statefsm;
stat: process(clk) --current_stateànext_state
begin
if rising_edge (clk) then
current_state <=next_state;
end if;
end process stat;
end rtl;
1) 编码方式预设为时序编码
2) 使用两个进程语句来设计状态机
其综合电路如图2 所示。
其状态图如图3 所示。
Moore FSM 模拟波形如图4 所示。
模拟结果说明:
(1) 由于reset 为异步reset ,所以当reset在150ns~200ns为0时,则状态图会从s1回到s0.
(2) 在50 ns时输入x为0且现态为1,在70 ns 时clk上升沿触发且x为1,则current_state会变成next_state s2;
接下来我们要介绍Mealy状态机,它和输入、输出、状态皆有关。它的状态图、状态表与Moore状态机都有所不同,输出会随输入变化而变化。如图5 所示。
0/0 |
图5:
S0S1S3S20/11/10/10/01/11/0 1/0
若现态为s0输入为0时,则次态为s0且输出为0;若现态为s0输入为1时,则次态为s1且输出为1。
根据这个规则,列出Mealy状态机的状态表如表3。
现态 |
次态 |
输出 |
||
输入 |
X=0 |
X=1 |
X=0 |
X=1 |
S0 |
S0 |
S1 |
0 |
1 |
S1 |
S2 |
S1 |
1 |
0 |
S2 |
S3 |
S0 |
0 |
1 |
S3 |
S0 |
S3 |
1 |
0 |
其Mealy状态机的VHDL如下所示:
Library ieee;
Use ieee.std_logic_1164.all;
Use ieee.numeric_std.all;
Entity melay_fsm is
Port(
clk: : in std_logic;
rstn : in std_logic;
x : in std_logic;
output : out std_logic
);
End moore_fsm;
Architecture rtl of moore_fsm is
Type state is (s0,s1,s2,s3); ---状态定义
Signal current_state : state; ---现态
Signal next_state : state; ---次态
Begin
Statefsm: process(rstn, x, current_state)
Begin
If rstn = ‘0’ then --异步reset
next_state <= s0;
output <= ‘0’;
else
case current_state is
when s0 =>
if x =’0’ then
next_state <= s0;
else
next_state <= s1;
end if;
if x= ‘0’ then
output <= ‘0’;
else
output <= ‘1’;
end if;
when s1 =>
if x =’0’ then
next_state <= s2;
else
next_state <= s1;
end if;
if x= ‘0’ then
output <= ‘1’;
else
output <= ‘0’;
end if;
when s2 =>
if x =’0’ then
next_state <= s3;
else
next_state <= s0;
end if;
if x= ‘0’ then
output <= ‘0’;
else
output <= ‘1’;
end if;
when s3 =>
if x =’0’ then
next_state <= s0;
else
next_state <= s3;
end if;
if x= ‘0’ then
output <= ‘1’;
else
output <= ‘0’;
end if;
end case;
end if;
end process statefsm;
stat: process(clk) --current_stateànext_state
begin
if prsing_edge (clk) then
current_state <=next_state;
end if;
end process stat;
end rtl;
Mealy状态机综合电路如图6 所示。