打印
[Actel FPGA]

什么是“状态机”

[复制链接]
2247|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
6019赵文|  楼主 | 2010-1-17 15:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
六楼的窗户| | 2010-1-17 15:06 | 只看该作者
 关于状态机的一个极度确切的描述是它是一个有向图形,由一组节点和一组相应的转移函数组成。状态机通过响应一系列事件而“运行”。每个事件都在属于“当前” 节点的转移函数的控制范围内,其中函数的范围是节点的一个子集。函数返回“下一个”(也许是同一个)节点。这些节点中至少有一个必须是终态。当到达终态, 状态机停止。
  包含一组状态集(states)、一个起始状态(start state)、一组输入符号集(alphabet)、一个映射输入符号和当前状态到下一状态的转换函数(transition function)的计算模型。当输入符号串,模型随即进入起始状态。它要改变到新的状态,依赖于转换函数。在有限状态机中,会有有许多变量,例如,状态 机有很多与动作(actions)转换(Mealy机)或状态(摩尔机)关联的动作,多重起始状态,基于没有输入符号的转换,或者指定符号和状态(非定有 限状态机)的多个转换,指派给接收状态(识别者)的一个或多个状态,等等。
  传统应用程序的控制流程基本是顺序的:遵循事先设定的逻辑,从头到尾地执行。很少有事件能改变标准执行流程;而且这些事件主要涉及异常情况。“命令行实用程序”是这种传统应用程序的典型例子。
  另一类应用程序由外部发生的事件来驱动——换言之,事件在应用程序之外生成,无法由应用程序或程序员来控制。具体需要执行的代码取决于接收到的事件,或者它 相对于其他事件的抵达时间。所以,控制流程既不能是顺序的,也不能是事先设定好的,因为它要依赖于外部事件。事件驱动的GUI应用程序是这种应用程序的典 型例子,它们由命令和选择(也就是用户造成的事件)来驱动。
  Web应用程序由提交的表单和用户请求的网页来驱动,它们也可划归到上述类 别。但是,GUI应用程序对于接收到的事件仍有一定程度的控制,因为这些事件要依赖于向用户显示的窗口和控件,而窗口和控件是由程序员控制的。Web应用 程序则不然,因为一旦用户采取不在预料之中的操作(比如使用浏览器的历史记录、手工输入链接以及模拟一次表单提交等等),就很容易打乱设计好的应用程序逻辑。
  显然,必须采取不同的技术来处理这些情况。它能处理任何顺序的事件,并能提供有意义的响应——即使这些事件发生的顺序和预计的不同。有限状态机正是为了满足这方面的要求而设计的。
  有限状态机是一种概念性机器,它能采取某种操作来响应一个外部事件。具体采取的操作不仅能取决于接收到的事件,还能取决于各个事件的相对发生顺序。之所以能 做到这一点,是因为机器能跟踪一个内部状态,它会在收到事件后进行更新。为一个事件而响应的行动不仅取决于事件本身,还取决于机器的内部状态。另外,采取 的行动还会决定并更新机器的状态。这样一来,任何逻辑都可建模成一系列事件/状态组合。
  [1]状态机可归纳为4个要素,即现态、条件、动作、次态。这样的归纳,主要是出于对状态机的内在因果关系的考虑。“现态”和“条件”是因,“动作”和“次态”是果。详解如下:
  ①现态:是指当前所处的状态。
  ②条件:又称为“事件”。当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。
  ③动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。
  ④次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。

使用特权

评论回复
板凳
米其林r| | 2010-1-17 15:06 | 只看该作者
VHDL之状态机学习笔记:转(鉴于状态机方面的问题太多,贴出此贴)

因为状态机的应用实在是太广泛了,例如各种存储器的控制,AD的控制外部器件的控制,也包括内部电路的控制,到了非学不可的地步了。

对于状态机的理论没有涉及太多,只有几点需要注意:

(1)moore和mealy的区别在于输出是否只和当前状态有关。

(2)状态机的两种基本操作:一是状态机内部状态的转换,另一是产生输出信号序列。

(3)状态机的分析可以从状态图入手,同样,状态机的设计也可以从状态图入手。

在集成电路设计时,通常可以将整个系统划分为两部分,一部分是数据单元,另一部分是控制单元。数据单元包含保存运算数据和运算结果的数据寄存器,也包括完成数据运算的组合逻辑。控制单元用来产生信号序列,以决定何时进行何种数据运算,控制单元要从数据单元得到条件信号,以决定继续进行那些数据运算。数据单元要产生输出信号,数据运算状态等有用信号。数据单元和控制单元中,有两个非常重要的信号,即复位信号和时钟信号。复位信号保证了系统初始状态的确定性,时钟信号则是时序系统工作的必要条件。状态机通常在复位信号到来的时候恢复到初始状态,每个时钟到来的时候内部状态发生变化。

正如上面的(3)提到的,设计状态机时一般先构造出状态图。构造状态图的一般方法是从一个比较容易描述的状态开始,通常初始态是一个很好开始的状态,也就是状态机复位以后开始的状态。在建立每个状态时最好都清楚的写出关于这个状态的文字描述,为硬件设计过程提供清晰的参考资料,也为最后完成的设计提供完整的设计文档。

下面给出一个用VHDL实现ADC0804控制器的完整设计过程。

首先根据ADC0804的时序图分析所有可能的状态,并且建立起来状态图。

时序图:

http://pic13.album.tom.com/album ... 4%6a%77%49%71%6d%74

4个状态如下:

idle: CS=0,WR=0,RD=1 启动AD0804开始转换

convert:CS=1,WR=1,RD=1,AD0804进行数据转换

read1: CS=1,WR=1,RD=1,INTR,转换结束,开始读

read2: CS=1,WR=1,RD=0,读取数据。

状态图:

http://pic13.album.tom.com/album ... 4%6a%77%4b%73%69%72

VHDL程序如下,所用的综合器是XST

--------------------------------------------------------------------------------
-- Design Name: skycanny
-- Module Name: ad_controller - Behavioral
-- Description: This VHDL design is created to implement a state machine
-- to control AD0804
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ad_controller is
port(
reset : in std_logic;
clk : in std_logic;
intr : in std_logic;
data_i : in std_logic_vector(7 downto 0);
data_o : out std_logic_vector(7 downto 0);
cs : out std_logic;
wr : out std_logic;
rd : out std_logic
);
end ad_controller;

architecture Behavioral of ad_controller is

type state is (start, convert, read1, read2);
signal current_state, next_state : state;
signal data_r : std_logic_vector(7 downto 0);
signal read_data : std_logic;

begin
sync :process(reset,clk)
begin
if(reset = '0') then
current_state <= start;
elsif(clk'event and clk = '1') then
current_state <= next_state;
end if;
end process sync;

comb :process(current_state, intr)
begin
case current_state is
when start =>
next_state <= convert;
cs <= '0';
wr <= '0';
rd <= '1';
read_data <= '0';
when convert =>
if(intr = '0') then
next_state <= read1;
else
next_state <= convert;
end if;
cs <= '1';
wr <= '1';
rd <= '1';
read_data <= '0';
when read1 =>
next_state <= read2;
cs <= '0';
wr <= '1';
rd <= '0';
read_data <= '1';
when read2 =>
next_state <= start;
cs <= '1';
wr <= '1';
rd <= '1';
read_data <= '0';
when others =>
next_state <= start;
end case;
end process comb;

get_data: process(reset,clk)
begin
if(reset = '0') then
data_r <= X"00";
elsif(clk'event and clk = '1') then
if(read_data = '1') then
data_r <= data_i;
end if;
end if;
end process;

data_o <= data_r;
end Behavioral;


功能仿真图:

http://pic13.album.tom.com/album ... 4%6a%77%4b%75%6d%73

从仿真图可以看出,该控制器工作正常。

RTL原理图:

http://pic13.album.tom.com/album ... 4%6a%77%4b%73%69%72

总结:对于时序电路中用到的状态机,分析时序电路中间经历的状态可以很快得出状态机的整体结构,然后用VHDL实现就可以。另外ISE提供了StateCad,方便了状态机的设计,仿真等等。

使用特权

评论回复
地板
beny5566| | 2010-1-17 15:21 | 只看该作者
想采用串行的结构就需要用到状态机

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

350

主题

1515

帖子

1

粉丝