semonpic 发表于 2010-11-22 20:37:45

VHDL写状态机的一个问题,希望大家注意

本人选择的FPGA是 EP2C8114,开发环境QUARTUS 9.0. 综合器用的是软件集成的,在用VHDL 构建状态机时发现一个容易犯的的错误。此错误,导致状态机状态转换的混乱。

状态机一般常用的是2段式和3段式的,在第二段中描述状态的转移。当设计的状态机是mealy型(状态的转移取决于输入的条件),在用if --else --end if,casewhen end case:描述时.一定要明确的描述状态在相应的输入条件的条件转移情况。

实例
http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_599699FV4JAI.png
图一 正确的状态转换图和条件 (原文件名:图一.png)
代码

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity fsmtest is
port(
        clk: in std_logic;
        rst :in std_logic;
        a,b,c: in std_logic

);
end entity;

architecture rtl of fsmtest is
                TYPE state is(idle,s1,s2);
                signal cs,ns:state;
               
                begin
                        process(clk,rst) --state trasmit
                                begin
                                        if(clk'event and clk='1') then
                                                if(rst='0') then
                                                        cs<=idle;
                                                else
                                                        cs<=ns;
                                                end if;
                                        end if;
                        end process;
                       
                        process(cs,a,b,c)
                                        begin
                                        case cs is
                                               
                                                when idle =>
                                                                if(a='1') then
                                                                        ns<=s1;
                                                               else
                                                                        ns<=idle;
                                                                end if;
                                                when s1 =>
                                                                        if(b='1') then
                                                                       ns<=s2;
                                                                       else
                                                                          --ns<=s1;
                                                                        end if;
                                                when s2 =>
                                                                case cis
                                                               when '1'=>ns <=idle;
                                                               when others=>
                                                                     ns<=s2;
                                                                end case;
                                                               
                                                when others =>
                                                                        ns <= idle;
                                                end case;       
                                end process;

end rtl;


在上述代码中有 3个条件状态的转移



                                          when idle =>

                                                      if(a='1') then

                                                               ns<=s1;

                                                         else

                                                               ns<=idle;

                                                      end if;

                                          when s1 =>

                                                               if(b='1') then

                                                                ns<=s2;

                                                                else

                                                               ns<=s1;

                                                               end if;

                                          when s2 =>

                                                

                                                      case cis

                                                         when '1'=>ns <=idle;

                                                         when others=>

                                                             ns<=s2;

                                                      end case;



在不满足转移条件是也需要明确的用ns<= (本状态).不然状态机就出现混乱。



如将                                                 if(a='1') then

                                                               ns<=s1;

                                                         else

                                                               ns<=idle;

                                                      end if;

改成

                                                      if(a='1') then

                                                               ns<=s1;

                                                      end if;



综合的结果是

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_599700O30VE0.png
图二 错误的状态装换图和转移条件 (原文件名:图2.png)
       把case cis

             when '1'=>ns <=idle;

            when others=>

               ns<=s2;

               end case;

中的NS<=S2注释掉以后,结果和上面一样。

个人感觉,在用VHDL描述状态迁移时,即使这次的状态转移条件不满足,也需要明确的描述出将当前的状态作为下一个转移状态。

       If (条件满足) then

         NS<=(下一个状态)

       Else

       NS<=(当前状态)

       End if;



      case 条件 is

       case 满足=> cs<=(下一个状态)

       case others=> ns<=(当前状态)

       end case
不知道别的综合器综合处的是啥效果

40130064 发表于 2010-11-22 22:53:29

process(cs,a,b,c)

是不是敏感信号多了
页: [1]
查看完整版本: VHDL写状态机的一个问题,希望大家注意