--- /dev/null
+-------------------------------------------------------------------------\r
+--\r
+-- Filename: ps2_keyboard_controller_beh.vhd\r
+-- =========\r
+--\r
+-- Short Description:\r
+-- ==================\r
+-- Behavioral implementation of the PS/2 keyboard controller.\r
+--\r
+-------------------------------------------------------------------------\r
+\r
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use work.ps2_transceiver_pkg.all;\r
+\r
+architecture beh of ps2_keyboard_controller is\r
+ type KEYBOARD_STATE_TYPE is\r
+ (\r
+ INIT, INIT_WAIT_ACK, INIT_WAIT_BAT, SET_INDICATORS_CMD, SET_INDICATORS_CMD_WAIT_ACK, SET_INDICATORS_VALUE,\r
+ SET_INDICATORS_VALUE_WAIT_ACK, ENABLE, ENABLE_WAIT_ACK, OPERATIONAL, NEW_DATA_AVAILABLE,\r
+ ERROR\r
+ );\r
+ signal keyboard_state, keyboard_state_next : KEYBOARD_STATE_TYPE; \r
+ \r
+ signal keyboard_data : std_logic_vector(7 downto 0);\r
+ signal keyboard_new_data : std_logic;\r
+ \r
+ signal input_data : std_logic_vector(7 downto 0);\r
+ signal input_data_send_ok, input_data_send_finished, send_request : std_logic;\r
+ \r
+ signal new_data_next : std_logic;\r
+ signal data_next, data_internal : std_logic_vector(7 downto 0);\r
+begin\r
+ ps2_transceiver_inst : ps2_transceiver\r
+ generic map\r
+ (\r
+ CLK_FREQ => CLK_FREQ,\r
+ SYNC_STAGES => SYNC_STAGES\r
+ )\r
+ port map\r
+ (\r
+ sys_clk => sys_clk,\r
+ sys_res_n => sys_res_n,\r
+ ps2_clk => ps2_clk,\r
+ ps2_data => ps2_data,\r
+ send_request => send_request,\r
+ input_data => input_data,\r
+ input_data_send_ok => input_data_send_ok,\r
+ input_data_send_finished => input_data_send_finished,\r
+ output_data => keyboard_data,\r
+ new_data => keyboard_new_data\r
+ );\r
+\r
+ process(keyboard_state, keyboard_new_data, keyboard_data, input_data_send_ok, input_data_send_finished)\r
+ begin\r
+ keyboard_state_next <= keyboard_state;\r
+ \r
+ case keyboard_state is\r
+ when INIT =>\r
+ if input_data_send_finished = '1' then\r
+ if input_data_send_ok = '1' then\r
+ keyboard_state_next <= INIT_WAIT_ACK;\r
+ else\r
+ keyboard_state_next <= ERROR;\r
+ end if;\r
+ end if;\r
+\r
+ when INIT_WAIT_ACK =>\r
+ if keyboard_new_data = '1' then\r
+ if keyboard_data = x"FA" then\r
+ keyboard_state_next <= INIT_WAIT_BAT;\r
+ else\r
+ keyboard_state_next <= ERROR;\r
+ end if;\r
+ end if;\r
+\r
+ when INIT_WAIT_BAT =>\r
+ if keyboard_new_data = '1' then\r
+ if keyboard_data = x"AA" then\r
+ keyboard_state_next <= SET_INDICATORS_CMD;\r
+ else\r
+ keyboard_state_next <= ERROR;\r
+ end if;\r
+ end if;\r
+ \r
+ when SET_INDICATORS_CMD =>\r
+ if input_data_send_finished = '1' then\r
+ if input_data_send_ok = '1' then\r
+ keyboard_state_next <= SET_INDICATORS_CMD_WAIT_ACK;\r
+ else\r
+ keyboard_state_next <= ERROR;\r
+ end if;\r
+ end if;\r
+ when SET_INDICATORS_CMD_WAIT_ACK =>\r
+ if keyboard_new_data = '1' then\r
+ if keyboard_data = x"FA" then\r
+ keyboard_state_next <= SET_INDICATORS_VALUE;\r
+ else\r
+ keyboard_state_next <= ERROR;\r
+ end if; \r
+ end if;\r
+ when SET_INDICATORS_VALUE =>\r
+ if input_data_send_finished = '1' then\r
+ if input_data_send_ok = '1' then\r
+ keyboard_state_next <= SET_INDICATORS_VALUE_WAIT_ACK;\r
+ else\r
+ keyboard_state_next <= ERROR;\r
+ end if;\r
+ end if;\r
+ when SET_INDICATORS_VALUE_WAIT_ACK =>\r
+ if keyboard_new_data = '1' then\r
+ if keyboard_data = x"FA" then\r
+ keyboard_state_next <= ENABLE;\r
+ else\r
+ keyboard_state_next <= ERROR;\r
+ end if;\r
+ end if;\r
+ \r
+ when ENABLE =>\r
+ if input_data_send_finished = '1' then\r
+ if input_data_send_ok = '1' then\r
+ keyboard_state_next <= ENABLE_WAIT_ACK;\r
+ else\r
+ keyboard_state_next <= ERROR;\r
+ end if;\r
+ end if;\r
+ when ENABLE_WAIT_ACK =>\r
+ if keyboard_new_data = '1' then\r
+ if keyboard_data = x"FA" then\r
+ keyboard_state_next <= OPERATIONAL;\r
+ else\r
+ keyboard_state_next <= ERROR;\r
+ end if;\r
+ end if; \r
+\r
+ when OPERATIONAL =>\r
+ if keyboard_new_data = '1' then\r
+ keyboard_state_next <= NEW_DATA_AVAILABLE;\r
+ end if;\r
+ \r
+ when NEW_DATA_AVAILABLE =>\r
+ keyboard_state_next <= OPERATIONAL;\r
+ \r
+ when ERROR =>\r
+ null;\r
+ end case;\r
+ end process;\r
+ \r
+ process(keyboard_state, keyboard_data, data_internal)\r
+ begin\r
+ send_request <= '0';\r
+ input_data <= x"00";\r
+ new_data_next <= '0';\r
+ data_next <= data_internal;\r
+ \r
+ case keyboard_state is\r
+ when INIT =>\r
+ send_request <= '1';\r
+ input_data <= x"FF";\r
+ when INIT_WAIT_ACK =>\r
+ null;\r
+ when INIT_WAIT_BAT =>\r
+ null;\r
+ when SET_INDICATORS_CMD =>\r
+ send_request <= '1';\r
+ input_data <= x"ED";\r
+ when SET_INDICATORS_CMD_WAIT_ACK =>\r
+ null;\r
+ when SET_INDICATORS_VALUE =>\r
+ send_request <= '1';\r
+ input_data <= x"02";\r
+ when SET_INDICATORS_VALUE_WAIT_ACK =>\r
+ null;\r
+ when ENABLE =>\r
+ send_request <= '1';\r
+ input_data <= x"F4";\r
+ when ENABLE_WAIT_ACK =>\r
+ null;\r
+ when OPERATIONAL =>\r
+ null;\r
+ when NEW_DATA_AVAILABLE =>\r
+ new_data_next <= '1';\r
+ data_next <= keyboard_data;\r
+ when ERROR =>\r
+ end case;\r
+ end process;\r
+\r
+ process(sys_clk, sys_res_n)\r
+ begin\r
+ if sys_res_n = '0' then\r
+ keyboard_state <= INIT;\r
+ new_data <= '0';\r
+ data_internal <= (others => '0');\r
+ elsif rising_edge(sys_clk) then\r
+ keyboard_state <= keyboard_state_next;\r
+ new_data <= new_data_next;\r
+ data_internal <= data_next;\r
+ end if;\r
+ end process;\r
+ data <= data_internal;\r
+end architecture beh;\r