Vhdl 状态机;为什么只有最后一个州在工作?

Vhdl 状态机;为什么只有最后一个州在工作?,vhdl,state-machine,fsm,case-when,Vhdl,State Machine,Fsm,Case When,我有一个具有6种状态(3种主要状态)的状态机。只有最后一个状态在工作,但前两个不工作(共3个)。只有最后一个状态在工作。我发现了问题,当我移除去抖动电路时,它可以工作,但我需要去抖动电路。我从网上得到了去抖动电路。如果有人能帮忙,我会很高兴的 type SM_STATES is (state_column_1, scan_col_1, state_column_2, scan_col_2, state_column_3, scan_col_3

我有一个具有6种状态(3种主要状态)的状态机。只有最后一个状态在工作,但前两个不工作(共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; 
scanner\u sm:进程(clk)
开始--处理密钥\u扫描器
如果clk'事件和clk='1',则
如果state_inc='1',那么——时钟除法器完成了100000的倒计时
--重置扫描完成
扫描完成
扫描值“0”);

原始col SCANED(已扫描)val SCANED(已扫描)val(已扫描)val(已扫描)到目前为止,您的代码不完整-您可以在案例语句中直接将信号分配给状态机评估的“我的状态”。为了理解这个问题,我们需要了解模拟器是如何工作的:

与实际硬件相比,模拟器必须以顺序方式使用顺序CPU处理代码。这是通过在无限小的时间距离(所谓的时间距离)内反复运行代码来实现的,直到所有依赖项都已解决,即不再有任何更改

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

您的示例基本上类似于一个无限循环:my_state的更改总是导致my_state的下一次更改,因此模拟器永远不会固定到一个值,直到它达到硬编码迭代限制,在您的例子中,这是第三个状态

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

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; 
ieee库;
使用ieee.std_logic_1164.all;
实体foo是
最终实体foo;
foo的架构栏是
SM_状态类型为(状态_列_1、扫描_列_1、状态_列_2、扫描_列_2、状态_列_3、扫描_列_3);
发出我的状态信号,我的状态下一步:SM状态;
信号bcd_val:std_逻辑_向量(3到0):=“1110”;
信号时钟:标准逻辑:='1';
信号nRST:std_逻辑:='0';
信号扫描值:标准逻辑向量(6到0);
信号原始列:标准逻辑向量(2到0);
信号扫描完成:标准逻辑;
开始——架构栏
comb:进程(我的状态,bcd\u val)为
开始——过程baz
如果我的州是
当状态_列_1=>
扫描值“0”);

原始列扫描\u val扫描\u val扫描\u val您可以将其视为构建在迭代绑定的答案上

我实现了您的完整状态机过程:

library ieee;
use ieee.std_logic_1164.all;

entity foo is

end entity foo;

architecture fum 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:        SM_STATES;  -- defaults to SM_STATES'LEFT

    signal state_inc:       std_logic := '0';

    signal bcd_val:         std_logic_vector(3 downto 0) := "1110";
    signal clk:             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

scanner_sm: 
    process (clk)
    begin
        if clk'event and clk = '1' then

            if state_inc = '1' then

                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;

CLOCK:
    process 
    begin
       wait for 10 ns;
       clk <= not clk;
       if Now > 200 ns then
           wait;
       end if;
    end process;

STIMULUS:
    process
    begin
        wait for 30 ns;
        state_inc <= '1';
        wait;
    end process;

end architecture;
礼物在哪里

  if state_inc = '1' then

这将使任何人都有机会在进入状态列1之前对扫描完成做出反应。您可能需要检查complete是否应命名为start_或_complete,并作为第一个状态

我对您的流程所做的唯一一件事就是更改缩进,以便更容易看到if语句中的所有内容


(我们警告过您,我们希望看到更多您的模型)

您为什么要在Stackoverlow和Stackexchange上发布此消息?没有足够的源代码来回答这个问题,请演示“只有最后一个状态有效,但前两个状态无效(共3个)”。要么包括一个工作测试台,要么显示(希望高分辨率)波形图像。我添加了我的整个过程。我只有一个顶级水平,我用互联网上的例子写了它,这是我写的第一个例子。我不能写完整的源代码。我知道这没有道理,但我不能…我没有一个复位按钮,其实我的电路。。。我可以不用它吗?我在问题中添加了我的完整过程源代码,我有一个时钟和时钟分频器,所以我认为我的时钟应该处理你所说的状态切换,但是我错过了我的下一个状态。我将集中精力实施我的下一个州。我周末没有FPGA,周一我会尝试给出反馈,谢谢你的提示!你也可以分享你的测试平台吗?经过再三考虑,我想我可以使用FPGA的一个按钮来“重置”,但如果有一种方法可以解决这个问题而不重置,我会选择这种方法。你可以分享你的测试平台文件吗?复制并粘贴上述VHDL源代码到一个文件中,进行分析、阐述和模拟。VHDL测试平台有一个通常可以识别的特征,即实体声明中缺少端口接口。如果需要,测试台还将包含一个时钟源,以及执行VHDL设计规范的刺激。这一个的独特之处在于,您只提供了一个流程,因此没有组件实例化,而是直接合并了您的流程。我终于找到了切换不起作用的原因,因为我的去盎司电路。当我删除去抖动电路时,它会工作。我从网上复制了这张底片。这个逻辑对我来说是有道理的,但我不知道为什么它不起作用。我在问题中加入了我的去盎司电路。