at main 80 lines 3.1 kB view raw
1-- ======================================================================== 2-- PS2 Keyboard Decoder 3-- Receives serial data from a PS2 keyboard and outputs which 4-- WASD keys are currently held down. 5-- 6-- PS2 protocol: 11 bits per key event (start, 8 data LSB first, parity, stop) 7-- Make code = key pressed, F0 + code = key released 8-- Scan codes: W=1D, A=1C, S=1B, D=23 9-- ======================================================================== 10 11library IEEE; 12use IEEE.STD_LOGIC_1164.all; 13use IEEE.STD_LOGIC_UNSIGNED.all; 14 15entity ps2_decoder is 16 port( 17 ps2_clk : in std_logic; -- clock from keyboard 18 ps2_data : in std_logic; -- serial data from keyboard 19 key_w : out std_logic; -- '1' when W is held 20 key_a : out std_logic; -- '1' when A is held 21 key_s : out std_logic; -- '1' when S is held 22 key_d : out std_logic -- '1' when D is held 23 ); 24end ps2_decoder; 25 26architecture behavior of ps2_decoder is 27 signal shift_reg : std_logic_vector(10 downto 0); 28 signal bit_count : std_logic_vector(3 downto 0) := (others => '0'); 29 signal break_flag : std_logic := '0'; 30 signal scan_code : std_logic_vector(7 downto 0); 31begin 32 33 -- Single process: shift in bits, decode when frame complete 34 ps2_receive : process(ps2_clk) 35 begin 36 if ps2_clk'event and ps2_clk = '0' then 37 -- Shift in new bit (MSB first into shift register) 38 shift_reg <= ps2_data & shift_reg(10 downto 1); 39 40 if bit_count = "1010" then 41 -- 11th bit received (stop bit), frame complete 42 -- Data byte is in shift_reg(9 downto 2) at this point: 43 -- shift_reg(10) = parity (from previous edge) 44 -- shift_reg(9) = data bit 7 45 -- shift_reg(2) = data bit 0 46 -- shift_reg(1) = start bit 47 scan_code <= shift_reg(9 downto 2); 48 49 -- Decode: F0 means next byte is a key release 50 if shift_reg(9 downto 2) = X"F0" then 51 break_flag <= '1'; 52 elsif break_flag = '1' then 53 -- Key released 54 break_flag <= '0'; 55 case shift_reg(9 downto 2) is 56 when X"1D" => key_w <= '0'; 57 when X"1C" => key_a <= '0'; 58 when X"1B" => key_s <= '0'; 59 when X"23" => key_d <= '0'; 60 when others => null; 61 end case; 62 else 63 -- Key pressed 64 case shift_reg(9 downto 2) is 65 when X"1D" => key_w <= '1'; 66 when X"1C" => key_a <= '1'; 67 when X"1B" => key_s <= '1'; 68 when X"23" => key_d <= '1'; 69 when others => null; 70 end case; 71 end if; 72 73 bit_count <= (others => '0'); 74 else 75 bit_count <= bit_count + 1; 76 end if; 77 end if; 78 end process ps2_receive; 79 80end behavior;