原创 VHDL之状态机学习笔记

2006-12-7 13:16 4729 13 17 分类: FPGA/CPLD
 


        由于平时比较忙,没有时间系统的学习,所以一般情况下只能周末稍微系统的学习一下。前几周主要学习了一下如何用VHDL来实现一个状态机。因为状态机的应用实在是太广泛了,例如各种存储器的控制,AD的控制外部器件的控制,也包括内部电路的控制,到了非学不可的地步了。


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


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


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


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


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


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


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


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


时序图:


http://pic13.album.tom.com/album_pic/2005/09/12/b15fe2073e48e1bb3780e6431f695e8c?%75%4e%6f%44%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_pic/2005/09/12/8427a2ae7a7a9c03018d4f83dfce23a4?%75%4e%6f%44%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_pic/2005/09/12/da734f0b3c9a730aed2a367e13d9f833?%75%4e%6f%44%6a%77%4b%75%6d%73


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


RTL原理图:


http://pic13.album.tom.com/album_pic/2005/09/12/8427a2ae7a7a9c03018d4f83dfce23a4?%75%4e%6f%44%6a%77%4b%73%69%72


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

PARTNER CONTENT

文章评论4条评论)

登录后参与讨论

用户52478 2009-12-29 17:43

谢谢。希望介绍更多。最好出书,我买一本。做医疗电子的人少呀

用户60452 2007-5-15 22:01

最好使用两个状态机,如果两个状态机不是同源时钟的话,那就设计同步信号同步两个状态机

用户31204 2007-3-20 14:59

xiexie

 

用户185277 2006-12-15 09:59

ash_riple_768180695 2006-12-12 08:49

博主的文章分析的很到位,许多很关键的地方都指出来了,值得大家细读。

ash_riple_768180695 2006-12-12 08:48

state cad确实不错。投一票。
相关推荐阅读
用户60452 2008-11-14 20:53
原创java连载--泛型(7)
类型擦除(Type Erasure)       当我们实例化一个泛型的时候,编译器使用一种叫做类型擦除(type erasure)的技术。在类型擦除的过程中,编译器会去除掉 类与接口中所有和类型参数...
用户60452 2008-11-13 22:08
原创java连载--泛型(6)
通配符       在泛型中,我们可以用一个通配符”?”来代替一个未知的类型。例如,使用下面的代码为某种animal指定一个cage:Cage<? extends Animal> some...
用户60452 2008-11-12 20:59
原创java连载--泛型(5)
泛型的子类型       只要两种类型能够相符,我们可以把一种类型的对象赋给另外一种类型的对象。例如,可以把一个Integer赋给一个Object,因为Object是Integer的父类之一。    ...
用户60452 2008-11-10 22:20
原创java连载--泛型(4)
受限的类型参数(Bounded Type Parameters)       有时候,我们要限制传递给类型参数的具体参数。例如,对数进行操作的方法就只能接受Number或者其子类的对象作为改方法的参数...
用户60452 2008-11-09 21:49
原创java连载--泛型(3)
泛型方法和构造器       如果在申明方法或者构造器的时候使用类型参数的话,就可以定义泛型方法和泛型构造器。这和定义一个普通的泛型基本上无二样,除了类型参数的作用范围只是在定义它的方法或者构造器之中...
用户60452 2008-11-08 19:13
原创java连载--泛型(2)
我们可以通过将"public class Box" 修改为 "public class Box<T>"而定义一个泛型,在这个定义中,使用了一个类型变量(type variable) T,而...
EE直播间
更多
我要评论
4
13
关闭 站长推荐上一条 /3 下一条