状态机;为什么只有最后一个状态在工作? [英] State machine; why only last state is working?
问题描述
我有一个有 6 个状态(3 个主要状态)的状态机.只有最后一个状态有效,但前 2 个状态无效(共 3 个).只有最后一个状态有效.我发现了问题,当我移除去抖动电路时它可以工作,但我需要去抖动电路.我从互联网上得到了去抖动电路.如果有人可以提供帮助,我会很高兴.
I have a state machine with 6 states(3 main states). Only the last state is working but the first 2 doesn't(out of 3).Only the last state is working. I found out the problem, when I remove the debounce circuit it works, but I need the debouncing circuit. I got the debouncing circuit from the internet. I would be glad if someone can help.
type SM_STATES is (state_column_1, scan_col_1, state_column_2, scan_col_2,
state_column_3, scan_col_3);
signal my_state : SM_STATES := state_column_1;
下面是状态机:
scanner_sm : process (clk)
begin -- process key_scanner
if clk'event and clk = '1' then
if state_inc = '1' then -- clock divider finished counting down 100000
-- reset scan_complete
scan_complete <= '0';
case my_state is
when state_column_1 =>
scanned_val <= (others => '0');
original_col <= "110";
my_state <= scan_col_1;
when scan_col_1 =>
case bcd_val is
when "1110" => scanned_val <= "1100100"; -- 1 wrong
when "1101" => scanned_val <= "1100010"; -- 2 wrong
when others => scanned_val <= "0010000";
end case;
my_state <= state_column_2;
when state_column_2 =>
original_col <= "011";
my_state <= scan_col_2;
when scan_col_2 =>
case bcd_val is
when "1110" => scanned_val <= "1011011"; -- 5 wrong
when "1101" => scanned_val <= "1011111"; -- 6 wrong
when others => scanned_val <= "0000000";
end case;
my_state <= state_column_3;
when state_column_3 =>
original_col <= "101";
my_state <= scan_col_3;
when scan_col_3 => -- Reading S1 // The only working state
case bcd_val is
when "1110" => scanned_val <= "1100000"; -- 9/ 1
when "1101" => scanned_val <= "0111110"; -- X/ 2
when others => scanned_val <= "0000000";
end case;
my_state <= state_column_1; -- ************ Error might be here
scan_complete <= '1'; -- ********** Error might be here
when others => scanned_val <= "0000000";
end case;
end if;
end if;
end process scanner_sm;
debounce: process (CLK) is
begin
if (CLK'event and CLK = '1') then
Q0 <= scannel_val;
Q1 <= Q0;
Q2 <= Q1;
end if;
end process;
Final_val <= Q0 and Q1 and (not Q2);
end Behavioral;
推荐答案
到目前为止您的代码是不完整的 - 您在 case 语句中直接分配给由状态机评估的信号 my_state.要理解这个问题,我们需要知道模拟器是如何工作的:
Your code so far is incomplete - you directly assign within your case statement to the signal my_state which is evaluated by the state machine. To understand the problem with this we need to know how the simulator works:
与实际硬件相比,模拟器必须按顺序使用顺序 CPU 处理代码.这是通过在无穷小的时间距离内一遍又一遍地运行代码来实现的 - 所谓的 Delta 延迟 - 直到所有依赖项都解决了,即没有任何变化.
In comparison to actual hardware the simulator has to process the the code with a sequential CPU in a sequential matter. This works by running through the code over and over again in infinitesimal time distances - the so called Delta delay - until all dependencies have resolved, i.e. nothing changes anymore.
请注意,在此迭代期间没有经过实际时间.在正确编写的设计中,模拟器现在等待下一个事件发生 - 通常是由再次重新启动顺序迭代的时钟滴答引起的.
Note that no actual time has passed during this iterations. In a correctly written design the simulator now waits until the next event occurs - usually caused by the tick of a clock which again restarts the sequential iterations.
您的示例基本上类似于一个无限循环:my_state 的更改总是会导致 my_state 的下一次更改,因此模拟器永远不会确定一个值 - 直到它达到硬编码的迭代限制,这碰巧在你的情况下是第三种状态.
Your example basically resembles an infinite loop: a change of my_state always causes the next change of my_state and thus the simulator never settles to a value - until it reaches a hardcoded iteration limit which, by chance in your case is the third state.
那么,如何解决这个问题?我们需要引入一个时钟,需要根据实际仿真时间进行状态转换,通常是等待一个时钟事件.最佳做法是将组合部分和顺序部分分成两个不同的过程,如状态机的这个最小示例所示:
So, how to fix this? We need to introduce a clock and need to make the state transition depending on the actual simulation time, usually by waiting for a clock event. Best practice is to separate the combinatoric and sequential parts into two different processes as shown in this minimal example of your state machine:
library ieee;
use ieee.std_logic_1164.all;
entity foo is
end entity foo;
architecture bar of foo is
type SM_STATES is (state_column_1, scan_col_1, state_column_2, scan_col_2, state_column_3, scan_col_3);
signal my_state, my_state_next : SM_STATES;
signal bcd_val : std_logic_vector(3 downto 0) := "1110";
signal clk : std_logic := '1';
signal nRST : std_logic := '0';
signal scanned_val : std_logic_vector(6 downto 0);
signal original_col : std_logic_vector(2 downto 0);
signal scan_complete : std_logic;
begin -- architecture bar
comb : process (my_state, bcd_val) is
begin -- process baz
case my_state is
when state_column_1 =>
scanned_val <= (others => '0');
original_col <= "110";
my_state_next <= scan_col_1;
when scan_col_1 =>
case bcd_val is
when "1110" => scanned_val <= "1100100"; -- 1 wrong
when "1101" => scanned_val <= "1100010"; -- 2 wrong
when others => scanned_val <= "0010000";
end case;
my_state_next <= state_column_2;
when state_column_2 =>
original_col <= "011";
my_state_next <= scan_col_2;
when scan_col_2 =>
case bcd_val is
when "1110" => scanned_val <= "1011011"; -- 5 wrong
when "1101" => scanned_val <= "1011111"; -- 6 wrong
when others => scanned_val <= "0000000";
end case;
my_state_next <= state_column_3;
when state_column_3 =>
original_col <= "101";
my_state_next <= scan_col_3;
when scan_col_3 => -- Reading S1 // The only working state
case bcd_val is
when "1110" => scanned_val <= "1100000"; -- 9/ 1
when "1101" => scanned_val <= "0111110"; -- X/ 2
when others => scanned_val <= "0000000";
end case;
my_state_next <= state_column_1; -- ************ Error might be here
scan_complete <= '1'; -- ********** Error might be here
when others => scanned_val <= "0000000";
end case;
end process comb;
process (clk, nRST) is
begin -- process
if nRST = '0' then -- asynchronous reset (active low)
my_state <= state_column_1;
elsif clk'event and clk = '1' then -- rising clock edge
my_state <= my_state_next;
end if;
end process;
-- this clock and reset signal would usually be supplied from the outside
clk <= not clk after 10 ns;
nRST <= '1' after 101 ns;
end architecture bar;
如果我们现在在模拟器中运行这个文件,我们可以看到每个时钟周期的状态切换:
If we run this file now within a simulator we can see the states switching with each clock cycle:
这篇关于状态机;为什么只有最后一个状态在工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!