gpt4 book ai didi

vhdl - 状态机;为什么只有最后一个状态有效?

转载 作者:行者123 更新时间:2023-12-01 23:56:24 24 4
gpt4 key购买 nike

我有一个有 6 个状态(3 个主要状态)的状态机。只有最后一个状态有效,但前 2 个状态无效(共 3 个)。只有最后一个状态有效。我发现了问题,当我移除去抖动电路时它可以工作,但我需要去抖动电路。我从互联网上得到了去抖动电路。如果有人可以提供帮助,我会很高兴。

 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。要理解这个问题,我们需要知道模拟器是如何工作的:

与实际硬件相比,模拟器必须使用顺序 CPU 按顺序处理代码。这是通过在无限小的时间距离内一遍又一遍地运行代码来实现的——即所谓的Delta delay。 - 直到所有依赖关系都已解决,即不再有任何变化。

请注意,在此迭代期间没有实际时间过去。在正确编写的设计中,模拟器现在会等待直到下一个事件发生 - 通常是由时钟的滴答声引起的,它会再次重新启动顺序迭代。

你的例子基本上类似于一个无限循环:my_state 的变化总是导致 my_state 的下一次变化,因此模拟器永远不会稳定到一个值 - 直到它达到硬编码的迭代限制,偶然在你的情况下是第三种状态。

那么,如何解决这个问题呢?我们需要引入时钟,需要根据实际仿真时间进行状态转换,通常是等待时钟事件。最佳做法是将组合部分和顺序部分分成两个不同的过程,如状态机的这个最小示例所示:

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;

如果我们现在在模拟器中运行这个文件,我们可以看到状态随每个时钟周期切换:

Simulation of the fixed code.

关于vhdl - 状态机;为什么只有最后一个状态有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23434772/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com