首页 > 解决方案 > PS2键盘界面状态问题

问题描述

我必须在大学里做一个项目,它是一个使用 FPGA 板(nexys2)的 PS2 键盘接口。我正在用 VHDL 编写代码,我遇到的问题是,在控制组件的某个地方,发送 11 位数据包的地方,当我按下一个键而不是在所有之后进入 START 状态时,进程卡在 GETBYTE3 状态位被正确接收并移入 FIFO 寄存器,它通过不同的状态运行并且永远不会正确进入 START。但是当我手动重置它时,通过在每次按下键盘上的任何键后将 CLR 切换为 1,它工作正常。

该系统的方式如下:当接收到扫描码时,它被转移到一个FIFO存储器中,在另一个组件中,它被解码并显示在7段显示器上。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ps2_src is
Port ( PS2C : in STD_LOGIC;
       PS2D : in STD_LOGIC;
       CLR : in STD_LOGIC;
          FIFO : out STD_LOGIC_VECTOR (31 downto 0);
          scan : out STD_LOGIC_VECTOR (7 downto 0);
          deb : out STD_LOGIC_VECTOR (7 downto 0));
end ps2_src;
architecture Behavioral of ps2_src is
type STATE_TYPE is (START, WCLKLO1, GETBYTE1, WCLKLO2, GETBYTE2, CHECK,     WCLKLO3, GETBYTE3);
signal state: STATE_TYPE := START;
signal tfifo: STD_LOGIC_VECTOR(31 downto 0) := X"11111111";
begin
control: process(CLR, PS2C)
     variable keyv1_temp, keyv2_temp, keyv3_temp: STD_LOGIC_VECTOR(7 downto     0);
     variable shift1, shift2, shift3: STD_LOGIC_VECTOR(10 downto 0);
     variable parity: STD_LOGIC;
     variable bit_cnt: NATURAL := 0;
     begin
    if CLR = '1' then
        state <= START;
        bit_cnt := 0;
    elsif   PS2C'EVENT and PS2C = '0' then
        case state is
                when START => 

                    if PS2D = '0' then
                        state <= START;
                    else
                        state <= WCLKLO1;
                    end if;
                    deb <= "00000000";

            when WCLKLO1 =>                      
                    shift1 := PS2D & shift1(10 downto 1);                           
                    bit_cnt := bit_cnt + 1;

                    if (bit_cnt = 11) then      
                        state <= GETBYTE1;
                    end if;
                    deb <= "00000010";

            when GETBYTE1 =>
                    keyv1_temp := shift1(8 downto 1);

                    parity := keyv1_temp(0) xor keyv1_temp(1) xor keyv1_temp(2) xor keyv1_temp(3) xor keyv1_temp(4) xor keyv1_temp(5) xor keyv1_temp(6) xor keyv1_temp(7);

                    bit_cnt := 0;
                    state <= WCLKLO2;
                    deb <= "00000100";

            when WCLKLO2 => 
                    shift2 := PS2D & shift2(10 downto 1);                           
                    bit_cnt := bit_cnt + 1;

                    if (bit_cnt = 11) then      
                        state <= GETBYTE2;
                    end if;
                    deb <= "00001000";

            when GETBYTE2 =>
                    keyv2_temp := shift2(8 downto 1);                               

                    bit_cnt := 0;
                    state <= CHECK;

                    scan <= keyv2_temp;
                    deb <= "00010000";

            when CHECK => 

                    if keyv2_temp = X"F8" then
                        deb <= "00100000";
                        state <= WCLKLO3;
                        tfifo <= tfifo(23 downto 0) & keyv1_temp;
                    else
                        if keyv1_temp = X"E0" then
                            deb <= "01000000";
                            state <= WCLKLO1;
                            tfifo <= tfifo(23 downto 0) & keyv2_temp;                   
                        else
                            deb <= "10000000";
                            state <= WCLKLO2;
                            tfifo <= tfifo(23 downto 0) & keyv1_temp;
                        end if;
                    end if;

            when WCLKLO3 => 
                    shift3 := PS2D & shift2(10 downto 1);                                                        
                    bit_cnt := bit_cnt + 1;

                    if (bit_cnt = 11) then      
                        state <= GETBYTE3;
                    end if;
                    deb <= "11000000";

            when GETBYTE3 =>                                                                                        keyv3_temp := shift3(8 downto 1);

                    bit_cnt := 0;
                    state <= START;
                    deb <= "10100000";

        end case;
    end if;
end process control;
FIFO <= tfifo;

end Behavioral;

标签: vhdl

解决方案


推荐阅读