跑丢的孩子

读书笔记之状态机

0
阅读(3062)

        花了几天的时间,终于看完了《Xlinx FPGA设计基础》一书。虽然是一本比较入门基础的书籍,但是还是颇有收获的。曾经听一培训老师说过,玩FPGA就是玩状态机,就自己目前水平而言,我不敢断言这句话正确与否,但是状态机是建模中使用非常普遍的一种建模结构。下面我就结合该书,对状态机做一下总结。

        状态机可以分为两类,Mealy型和Moore型。如何区分这两种状态机呢?本质区别是Moore型状态机的输出只与模块的当前状态有关,而Mealy型状态机的输出与模块的当前状态和当前的输入信号都有关系。然而,一般工程设计中遇到的状态描述问题都不是单纯的Moore型或单纯的Mealy型,而是他们的混合结构。一个完整的状态机包括状态的描述和状态机的描述。下面分别来讲述一下这两个部分。

1、状态的描述
(1)用枚举的方式定义状态机工作的不同状态。
ex:type  my_state is (s0,s1,s2,...)
通常,各个状态使用具有对应含义的名称,比如s0这个状态完成一些初始化的操作,我们可以将这一状态描述为init,这样做的目的是增强代码的可读性。
(2)将每一个工作状态用一个常量定义
ex:subtype  my_state is std_logic_vector(0 to 5)--定义一个子类型
       constant s0 : my_state:="00001";
       constant s1 : my_state:="00010
2、状态机的描述
(1)单进程描述
ex:process(clk,rst)
       begin
           if(rst='1')then
                state <= s0;
           elsif rising_edge(clk) then
                case state is
                    when s0=>...
                    when s1=>...
                    ...
在代码中只定义了一个state,输入信号控制不同状态之间的跳转。但是这种方法有一个致命的缺陷,就是在每一个输出端都会综合出一个寄存器,只有当时钟信号有效时,输出才会有效,带来的后果就是增加了一个周期的时延,而且还会浪费FPGA的逻辑资源。
(2)多进程描述
ex:process(clk,rst)
       begin
           if(rst='1')then
                current_state <= s0;
           elsif rising_edge(clk) then
                current_state <= next_state;
           end if;
        end process;
        process(current_state,ina,inb,...)
        begin
            case current_state is
                when s0 =>...
                when s1 =>...
                ...
            end case;
        end process;
多进程的描述从代码书写风格上就可以看出来,就是使用多个进程来描述状态机,。这种结构增强了代码的可读性,同时也省去了不必要的寄存器。