86 lines
2.3 KiB
VHDL
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;
|