terminal/keyboard.vhd

86 lines
2.3 KiB
VHDL

library ieee;
library unisim;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity keyboard is
generic (
input_clk: integer
);
port (
clk: in std_logic;
reset: in std_logic;
bytes_received: out std_logic_vector(5 downto 0);
ps2_scl: inout std_logic;
ps2_sda: inout std_logic
);
end keyboard;
architecture Behavioral of keyboard is
signal ps2_reset_n: std_logic;
signal ps2_clear_data_available: std_logic;
signal ps2_data_available: std_logic;
signal ps2_data_available_old: std_logic;
signal byte_count: std_logic_vector(5 downto 0);
begin
ps2_host: entity work.ps2 port map (
clk_i => clk,
rst_i => ps2_reset_n,
data_o => open,
data_i => "00000000",
ibf_clr_i => ps2_clear_data_available,
obf_set_i => '0', -- we don't want to write anything
ibf_o => ps2_data_available,
obf_o => open,
frame_err_o => open, -- ignore errors for now
parity_err_o => open,
busy_o => open,
err_clr_i => '0',
wdt_o => open,
ps2_clk_io => ps2_scl,
ps2_data_io => ps2_sda
);
-- count bytes received
main: process(clk, reset)
constant max_delay: integer := input_clk / 200_000; -- 5µs
variable delay: integer range 0 to max_delay := 0;
begin
if reset = '1' then
delay := 0;
byte_count <= "000000";
-- reset component
ps2_reset_n <= '0';
elsif rising_edge(clk) then
if delay = 5 then
-- init component
ps2_reset_n <= '1';
delay := delay + 1;
elsif delay = max_delay then
ps2_clear_data_available <= '0';
ps2_data_available_old <= ps2_data_available;
if ps2_data_available_old = '0' and ps2_data_available = '1' then
-- count rising edges on ps2_data_available:
byte_count <= byte_count + 1;
ps2_clear_data_available <= '1';
end if;
else
delay := delay + 1;
end if;
end if;
end process main;
bytes_received <= byte_count;
end Behavioral;