Vhdl 键盘编码器为什么有8个状态?

Vhdl 键盘编码器为什么有8个状态?,vhdl,state-machine,keypad,Vhdl,State Machine,Keypad,我需要用vhdl编写一个键盘编码器。我想用4个州来做。在第1列时,扫描第1行、第2行、第2行、第4行。我认为这样的4个州应该足够了,但我从互联网上找到的一个例子是8个州: key_scanner_sm : process (clk) begin -- process key_scanner if clk'event and clk = '1' then if state_inc = '1' then -- reset scan_complete

我需要用vhdl编写一个键盘编码器。我想用4个州来做。在第1列时,扫描第1行、第2行、第2行、第4行。我认为这样的4个州应该足够了,但我从互联网上找到的一个例子是8个州:

key_scanner_sm : process (clk)
  begin  -- process key_scanner
    if clk'event and clk = '1' then

      if state_inc = '1' then

        -- reset scan_complete
        scan_complete <= '0';

        case key_state is

          when pulse_row_1 =>
            key_read  <= (others => '0');
            key_row   <= "0001";
            key_state <= read_row_1;

          when read_row_1 =>
            case key_col is
              when "0001" => key_read <= X"31";  -- 1
              when "0010" => key_read <= X"32";  -- 2
              when "0100" => key_read <= X"33";  -- 3
              when "1000" => key_read <= X"41";  -- A
              when others => null;
            end case;
            key_state <= pulse_row_2;

          when pulse_row_2 =>
            key_row   <= "0010";
            key_state <= read_row_2;

          when read_row_2 =>
            case key_col is
              when "0001" => key_read <= X"34";  -- 4
              when "0010" => key_read <= X"35";  -- 5
              when "0100" => key_read <= X"36";  -- 6
              when "1000" => key_read <= X"42";  -- B
              when others => null;
            end case;
            key_state <= pulse_row_3;

          when pulse_row_3 =>
            key_row   <= "0100";
            key_state <= read_row_3;

          when read_row_3 =>
            case key_col is
              when "0001" => key_read <= X"37";  -- 7
              when "0010" => key_read <= X"38";  -- 8
              when "0100" => key_read <= X"39";  -- 9
              when "1000" => key_read <= X"43";  -- C
              when others => null;
            end case;
            key_state <= pulse_row_4;

          when pulse_row_4 =>
            key_row   <= "1000";
            key_state <= read_row_4;

          when read_row_4 =>
            case key_col is
              when "0001" => key_read <= X"2A";  -- *
              when "0010" => key_read <= X"30";  -- 0
              when "0100" => key_read <= X"23";  -- #
              when "1000" => key_read <= X"44";  -- D
              when others => null;
            end case;
            key_state     <= pulse_row_1;
            scan_complete <= '1';

          when others => null;
        end case;

      end if;
    end if;
  end process key_scanner_sm;
key\u scanner\u sm:进程(clk)
开始--处理密钥\u扫描器
如果clk'事件和clk='1',则
如果state_inc='1',则
--重置扫描完成
扫描完成
键_读取“0”);
键\行键\读取键\读取键\读取键\读取空;
终例;
基尤州
键\行键\读取键\读取键\读取键\读取空;
终例;
基尤州
键\行键\读取键\读取键\读取键\读取空;
终例;
基尤州
键\行键\读取键\读取键\读取键\读取空;
终例;

key_state您提供的示例需要额外的状态,因为它是作为单个case语句实现的。对
键列
的赋值需要额外的一个周期才能生效,然后才能读取
键列
。由于这是一个简单的循环扫描,
pulse\u row\u n
状态可以通过从前面的
read\u row\u n

中指定
key\u row
状态的下一个值来消除,因此我们可以简单地在4个状态下写入,我不明白为什么编码器在8个状态下这样做?为什么要把它弄得更复杂?我在寻找一个很好的理由,是吗?例如,为了防止出现按下两个按钮等情况,他们没有意识到有机会调整某些状态。你在网上看到的大多数VHDL代码质量都很差。它并不总是代表最佳实践。在这种情况下,循环被浪费并不重要,因为这是一个小逻辑,并且对于人类交互来说足够快。您需要注意的是实现过滤器来消除矩阵输入的抖动,以避免记录一个弹跳按钮的多次按下。在将外部信号直接送入去盎司滤波器之前,您还需要将
key\u col
输入同步到您的时钟域。需要避免的一个例子是用于同步过程的VHDL-87风格的时钟事件和时钟class='1'样板。您应该使用VHDL-93 rising_edge函数,因为它有一个对_X01的内部调用,以便在测试之前对时钟信号执行强度降低。这更具可读性,对于时钟可能为“H”或“L”的模拟情况下的正确行为非常重要。许多现代VHDL仍然以旧的方式编码,因为编写得很差,过时的教学材料。当我在不到15年的代码中看到VHDL-87时,我怀疑它的质量。正确的去抖动是非常重要的,我已经在这里以悬赏的方式问过了,如果你能在这方面帮助我,我会很高兴:你需要在设计中保持重置。有关原因的更多解释,请参阅。如果没有生产硬件,可以使用外部开关来控制复位,否则考虑使用生成内部复位的建议。