vga/ps/2: ip-core hinzugefuegt
[hwmod.git] / src / ps2 / ps2_keyboard_controller_beh.vhd
diff --git a/src/ps2/ps2_keyboard_controller_beh.vhd b/src/ps2/ps2_keyboard_controller_beh.vhd
new file mode 100644 (file)
index 0000000..ca9ca7d
--- /dev/null
@@ -0,0 +1,201 @@
+-------------------------------------------------------------------------\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