我目前正在尝试实现一个有5个不同状态的状态机。基本上,我想停留在一个状态,等待一段时间,进入下一个状态,等待不同的时间,进入下一个状态等等。
目前,我实现了一个计数器,它从一个1ms的信号中产生一个1s的信号,我在测试台中创建了这个信号。我创建了一个确定下一个状态的过程和一个从下一个状态升级当前状态的过程。没有表现出我预期的信号是:next_stateHS,它应该升级stateHS。相关代码在名为 "hsNextState "的过程中。我也无法解释的是,信号 "startCounter "的表现符合预期。这个信号在与信号 "next_StateHS "相同的 else - case中接收一个新的值,现在我将添加状态机和测试台的代码,以及模拟波形的图片.State machine:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity ampel is
port
(
clk : in std_ulogic;
reset : in std_ulogic;
enable : in std_ulogic;
haupt : out std_ulogic_vector(2 downto 0);
neben : out std_ulogic_vector(2 downto 0)
);
end ampel;
architecture ampel_behave of ampel is
--Codierung
-- idle = 000
-- gruen = 001
-- gelb = 010
-- rot = 011
-- rot_gelb = 100
signal stateHS, stateNS : std_ulogic_vector(2 downto 0) := (others => '0');
signal next_stateHS, next_stateNS : std_ulogic_vector(2 downto 0) := (others => '0');
signal startCounter : std_ulogic := '0';
signal counter : unsigned(9 downto 0) := (others => '0'); --für clk = 1ms im Testbench
signal count_seconds : unsigned(3 downto 0) := (others => '0');
begin
counterProcess : process(clk, reset, enable, startCounter)
begin
if enable = '0' or reset = '1' or startCounter = '0' then
counter <= (others => '0');
count_seconds <= (others => '0');
elsif rising_edge(clk) then
if counter < "1111101000" then
counter <= counter + 1;
else
counter <= (others => '0');
count_seconds <= count_seconds + 1;
end if;
end if;
end process counterProcess;
outputProcessHS : process(stateHS, reset, enable)
begin
if enable = '0' or reset = '1' then
haupt <= "000";
else
case (stateHS) is
when "000" =>
haupt <= "000";
when "001" =>
haupt <= "001";
when "010" =>
haupt <= "010";
when "011" =>
haupt <= "011";
when "100" =>
haupt <= "100";
when others =>
haupt <= "000";
end case;
end if;
end process outputProcessHS;
outputProcessNS : process(stateNS, reset, enable)
begin
if enable = '0' or reset = '1' then
neben <= "000";
else
case (stateNS) is
when "000" =>
neben <= "000";
when "001" =>
neben <= "001";
when "010" =>
neben <= "010";
when "011" =>
neben <= "011";
when "100" =>
neben <= "100";
when others =>
neben <= "000";
end case;
end if;
end process outputProcessNS;
hsNextState : process(reset, enable, stateHS, count_seconds)
begin
if enable = '0' or reset = '1' then
next_stateHS <= "000";
else
case (stateHS) is
when "000" =>
next_stateHS <= "001";
startCounter <= '1';
when "001" =>
if count_seconds < "1110" then
next_stateHS <= "001";
else
next_stateHS <= "010";
startCounter <= '0';
end if;
when "010" =>
next_stateHS <= "011";
when "011" =>
next_stateHS <= "100";
when "100" =>
next_stateHS <= "001";
when others =>
next_stateHS <= "000";
end case;
end if;
end process hsNextState;
hsState : process(reset, enable, next_stateHS, count_seconds)
begin
if enable = '0' or reset = '1' then
stateHS <= "000";
else
stateHS <= next_stateHS;
end if;
end process hsState;
-- nsStateProcess : process(reset, enable, stateNS, count_seconds)
-- begin
-- if enable = '0' or reset = '1' then
-- next_stateNS <= idle;
-- else
-- case (stateNS) is
-- when idle =>
-- next_stateNS <= gruen;
-- when gruen =>
-- next_stateNS <= gelb;
-- when gelb =>
-- next_stateNS <= rot;
-- when rot =>
-- next_stateNS <= rot_gelb;
-- when rot_gelb =>
-- next_stateNS <= gruen;
-- when others =>
-- next_stateNS <= idle;
-- end case;
-- end if;
-- stateNS <= next_stateNS;
-- end process nsStateProcess;
end ampel_behave;
测试台
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity ampel_tb is
end ampel_tb;
architecture test of ampel_tb is
component ampel
port
(
clk : in std_ulogic;
reset : in std_ulogic;
enable : in std_ulogic;
haupt : out std_ulogic_vector(2 downto 0);
neben : out std_ulogic_vector(2 downto 0)
);
end component;
signal clk : std_ulogic := '0';
signal reset : std_ulogic := '0';
signal enable : std_ulogic := '1';
signal haupt, neben : std_ulogic_vector(2 downto 0);
signal count_cycles : unsigned (19 downto 0) := (others => '0');
begin
ampel_1 : ampel port map
(
clk => clk,
reset => reset,
enable => enable,
haupt => haupt,
neben => neben
);
clock_signal : process
begin
if count_cycles < "0011100000000000000" then
clk <= '0';
wait for 500 us;
clk <= '1';
wait for 500 us;
count_cycles <= count_cycles + 1;
else
wait;
end if;
end process clock_signal;
end test;