-- -- --Original code from Ga Tech -- Keyboard module (provides exteranl inputs through PS2 Keyboard) -- Modified by B. Reese/MSU Mar 99 for better performance -- Library altera,IEEE,lpm; use altera.maxplus2.all; use IEEE.STD_LOGIC_1164.all; USE lpm.lpm_components.ALL; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_signed.all; entity Keyboard is Generic(DATA_LENGTH : integer := 9); port( reset : in std_Logic; Keyboard_DATA, Keyboard_CLOCK : in std_logic; clock : in std_Logic; parity_D,stopbit_D : out std_logic; key_stroke : out std_logic; k_data_D : out std_logic_vector(7 downto 0); key_ascii_D : out std_logic_vector(7 downto 0)); end Keyboard; -- -- Keyboard architecture -- architecture behavioral of Keyboard is signal k_data : std_logic_vector(DATA_LENGTH downto 0); signal nxt_k_data : std_logic_vector(DATA_LENGTH downto 0); signal key_ascii : std_logic_vector(5 downto 0); signal nxt_key_ascii : std_logic_vector(5 downto 0); signal receive_key : std_logic := '0'; signal nxt_receive_key : std_logic := '0'; signal start,stop_getkey : std_logic := '0'; signal cnt : std_logic_vector(3 downto 0) := "0000"; signal filter : std_logic_vector(7 downto 0); signal keyboard_clk_filt : std_logic; signal parityok : std_logic := '0'; signal shift_key : std_logic := '0'; -- Function Defined to Check the parity of the input signal. -- If the parity is correct, a '1' is returned else it is a '0'; function paritycheck(p_data : in std_logic_vector(8 downto 0)) return std_logic is variable Result: std_logic :='0'; begin xor_loop: FOR N IN p_data'range LOOP Result := Result xor p_data(N); END LOOP xor_loop; return Result; end function paritycheck; begin process (start, clock, cnt) variable cntclk : std_logic_vector(14 downto 0); begin wait until clock'event and clock = '1'; if start = '0' or cnt = "0000" then cntclk := "000000000000000"; stop_getkey <= '0'; else cntclk := cntclk + 1; if cntclk = "100111010000100" then stop_getkey <= '1'; end if; end if; end process; process begin wait until clock'event and clock='0'; filter(6 downto 0) <= filter(7 downto 1); filter(7) <= keyboard_clock; if filter = "00000000" then keyboard_clk_filt <= '0'; else keyboard_clk_filt <= '1'; end if; end process; process variable cnter : std_logic_vector(3 downto 0) := "0000"; begin wait until keyboard_clk_filt'event and keyboard_clk_filt = '0'; if keyboard_data ='0' and start = '0' then --(start = '0' or stop_getkey = '1') then start <= '1'; cnter := "0000"; nxt_k_data <= "0000000000"; else if start = '1' then cnter := cnter + 1; case cnter(3 downto 0) is when "0001" => nxt_k_data(0) <= Keyboard_DATA; when "0010" => nxt_k_data(1) <= Keyboard_DATA; when "0011" => nxt_k_data(2) <= Keyboard_DATA; when "0100" => nxt_k_data(3) <= Keyboard_DATA; when "0101" => nxt_k_data(4) <= Keyboard_DATA; when "0110" => nxt_k_data(5) <= Keyboard_DATA; when "0111" => nxt_k_data(6) <= Keyboard_DATA; when "1000" => nxt_k_data(7) <= Keyboard_DATA; when "1001" => nxt_k_data(8) <= Keyboard_DATA; when others => nxt_k_data(9) <= Keyboard_DATA; start <= '0'; nxt_receive_key <= not nxt_receive_key; end case; end if; end if; cnt <= cnter; end process; -- keyboard clock process scancode_rom: lpm_rom GENERIC MAP ( lpm_widthad => 8, lpm_numwords => "256", lpm_outdata => "UNREGISTERED", lpm_address_control => "UNREGISTERED", -- Reads in mif file for character generator data lpm_file => "scancode.mif", lpm_width => 6) PORT MAP ( --inclock => clock, address => nxt_k_data(7 downto 0), q => nxt_key_ascii); process begin wait until clock'event and clock ='1'; key_ascii <= nxt_key_ascii; k_data <= nxt_k_data; receive_key <= nxt_receive_key; end process; parityok <= paritycheck(k_data(8 downto 0)); process variable tmp_stroke, cur_key, break_code : std_logic := '0'; begin wait until clock'event and clock ='1'; if reset = '1' then key_ascii_D <= "00100000"; else k_data_d <= k_data(7 downto 0); if cur_key /= receive_key then cur_key := receive_key; parity_D <= parityok; stopbit_D <= k_data(9); if break_code = '0' then if k_data(7 downto 0) = "11110000" then break_code := '1'; else --do we have a valid key? --if k_data(9) = '1' and parityok = '1' then -- stop bit and parity check out ok -- the return, backspace, and shift keys all return key_ascii value -- of "111111" since these characters are not mapped directly to the -- tiny character generator ROM. Therefore, we assume (by default) that -- any key_ascii value not "111111" is a valid mapped key. if key_ascii /= "111111" then key_ascii_D(7 downto 0) <= "00" & key_ascii(5 downto 0); tmp_stroke := not tmp_stroke; key_stroke <= tmp_stroke; elsif k_data(7 downto 0) = "01011010" or -- return k_data(7 downto 0) = "01100110" then --backspace key_ascii_D(7 downto 0) <= k_data(6 downto 5) & "000000"; tmp_stroke := not tmp_stroke; key_stroke <= tmp_stroke; end if; if k_data(7 downto 0) = "00010010" or --Left Shift k_data(7 downto 0) = "01011001" then -- Right Shift shift_key <= '1'; end if; end if; -- if k_data(7 downto 0) else break_code := '0'; -- turn off shift during the break portion if (k_data(7 downto 0) = "00010010" or k_data(7 downto 0) = "01011001") then shift_key <= '0'; end if; end if; -- if break_code end if; -- if cur_key end if; -- if reset end process; end behavioral;