我正在尝试在 VHDL 中创建一个 FSM,它应该充当启动引擎的控制。当按正确顺序按下按钮 A 和 B 时(A-B-B,U1=1),发动机应启动。当按错误顺序按下时,U2=1。出现错误顺序时应按下重置按钮,然后才能输入正确的顺序。
我遇到的问题是多个时钟周期内的一个输入被读取为多个输入。我觉得我可能误解了什么。如何才能只读取一个输入? 我写了以下内容:
entity engine is
Port ( ab : in STD_LOGIC_VECTOR(1 downto 0);
clock : in STD_LOGIC;
ut : out STD_LOGIC_VECTOR(1 downto 0);
reset : in STD_LOGIC);
end engine;
architecture Behavioral of engine is
type state_type is (S0, S1, S2, S3, S4);
signal state, next_state : state_type;
begin
process(clock, reset)
begin
if reset = '1' then
next_state <= S0;
elsif rising_edge(clock) then
state <= next_state;
case state is
when S0 =>
if ab = "10" then -- press A
next_state <= S1;
end if;
when S1 =>
if ab = "01" then -- press B
next_state <= S2;
end if;
when S2 =>
if ab = "01" then -- press B
next_state <= S3;
elsif ab = "10" then
next_state <= S4;
end if;
when S3 =>
next_state <= S3;
when S4 =>
next_state <= S4;
end case;
end if;
end process;
process(state)
begin
case state is
when S0 =>
ut <= "00";
when S1 =>
ut <= "00";
when S2 =>
ut <= "00";
when S3 =>
ut <= "10";
when S4 =>
ut <= "01";
end case;
end process;
end Behavioral;
还有测试台:
ENTITY egninetest IS
END egninetest;
ARCHITECTURE behavior OF egninetest IS
COMPONENT engine
PORT(
ab : IN std_logic_vector(1 downto 0);
clock : IN std_logic;
ut : OUT std_logic_vector(1 downto 0);
reset : IN std_logic
);
END COMPONENT;
--Inputs
signal ab : std_logic_vector(1 downto 0) := (others => '0');
signal clock : std_logic := '0';
signal reset : std_logic := '0';
--Outputs
signal ut : std_logic_vector(1 downto 0);
-- Clock period definitions
constant clock_period : time := 15 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: engine PORT MAP (
ab => ab,
clock => clock,
ut => ut,
reset => reset
);
-- Clock process definitions
clock_process :process
begin
clock <= '0';
wait for clock_period;
clock <= '1';
wait for clock_period;
end process;
-- Stimulus process
stim_proc: process
begin
reset <= '1';
wait for 40 ns;
reset <= '0';
ab <= "01"; -- wrong input
wait for 55 ns;
reset <= '1'; -- test reset function
wait for 40 ns;
reset <= '0';
ab <= "10"; -- try correct input
wait for 40 ns;
ab <= "01";
wait;
end process;
END;
如果有不清楚的地方请询问,我知道我可能没有道理。
将中间状态添加到状态机中,代表按键之间之间的状态。
例如(使用您当前的州名称):