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
不知道别的综合器综合处的是啥效果 process(cs,a,b,c)
是不是敏感信号多了
页:
[1]