library IEEE; use IEEE.STD_LOGIC_1164.ALL; USE ieee.STD_LOGIC_UNSIGNED.all; entity ps2 is Port ( ps2_clk : in std_logic; ps2_data: in std_logic; clk: in std_logic; a: out std_logic; b: out std_logic; c: out std_logic; d: out std_logic ); end ps2; architecture Behavioral of ps2 is signal ps2_clk_int: std_logic; signal ps2_data_int: std_logic; signal ps2_clk_falling_edge: std_logic; signal last_ps2_clk: std_logic; signal started: std_logic; signal count: std_logic_vector(3 downto 0); signal data: std_logic_vector(9 downto 0); begin --syncronize external signals process(clk) begin if rising_edge(clk) then ps2_clk_int <= ps2_clk; ps2_data_int <= ps2_data; end if; end process; --detect clk egde process(clk) begin if rising_edge(clk) then last_ps2_clk <= ps2_clk_int; if last_ps2_clk = '1' and ps2_clk_int = '0' then ps2_clk_falling_edge <= '1'; else ps2_clk_falling_edge <= '0'; end if; end if; end process; --detect start bit process(clk) begin if rising_edge(clk) then if ps2_clk_falling_edge = '1' and ps2_data_int = '0' then --wait for start bit started <= '1'; end if; if count = "1010" then started <= '0'; end if; end if; end process; --shift in data process(clk) begin if rising_edge(clk) then if ps2_clk_falling_edge = '1' and started = '1' then count <= count + '1'; data <= ps2_data_int & data(9 downto 1); end if; if count = "1010" then count <= (others => '0'); end if; end if; end process; --decode scancode process(clk) begin if rising_edge(clk) then a <= '0'; b <= '0'; c <= '0'; d <= '0'; if count = "1010" and data(9) = '1' then --TODO: parity checken! if data(7 downto 0) = "00011100" then a <= '1'; end if; if data(7 downto 0) = "00110010" then b <= '1'; end if; if data(7 downto 0) = "00100001" then c <= '1'; end if; if data(7 downto 0) = "00100011" then d <= '1'; end if; end if; end if; end process; end Behavioral;