📄 ps2.vhd
字号:
-- The FPGA-evb-S2 Xilinx Spartan-II evaluation board example
--
-- This example reads scan codes from a PS/2 keyboard and
-- displays them on LEDs.
--
-- (C)2001 Jan Pech, j.pech@sh.cvut.cz
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ps2 is
port (resetn: in std_logic; -- active low reset
clock: in std_logic; -- system clock
ps2_clk: in std_logic; -- PS/2 clock line
ps2_dta: in std_logic; -- PS/2 data line
leds: out std_logic_vector(7 downto 0)); -- LED outputs
end ps2;
architecture behavioral of ps2 is
type state_type is (IDLE, START, DATA, PARITY); -- FSM states
signal ps2_dv: std_logic; -- PS/2 data valid
signal prv_ps2_clk, act_ps2_clk: std_logic; -- auxiliary signals
signal recdata: std_logic_vector(7 downto 0); -- read data
signal shift: std_logic; -- enable for shift reg.
signal n_shift: std_logic; -- auxiliary signal
signal latch: std_logic; -- latch read data
signal n_latch: std_logic; -- auxiliary signal
signal err: std_logic; -- parity or stop error
signal n_err: std_logic; -- auxiliary signal
signal parset: std_logic; -- preset for parity check
signal n_parset: std_logic; -- auxiliary signal
signal c_state, n_state: state_type; -- current & next states
signal cntval: std_logic_vector(2 downto 0); -- counter of data bits
signal zero: std_logic; -- counter is zero
signal parbit: std_logic; -- odd parity of data
begin
-- Provides a one-shot pulse after every falling edge of PS/2 clock
PS_CLK_SYNC: process(clock, resetn)
begin
if (resetn = '0') then
prv_ps2_clk <= '1';
act_ps2_clk <= '1';
elsif (clock'event and clock = '1') then
act_ps2_clk <= ps2_clk;
prv_ps2_clk <= act_ps2_clk;
end if;
end process;
ps2_dv <= (not act_ps2_clk) and prv_ps2_clk;
-- Serial input, parallel output shift register
SIPO: process(clock, resetn)
begin
if (resetn = '0') then
recdata <= (others => '0');
elsif (clock'event and clock = '1') then
if (shift = '1') then
recdata <= ps2_dta & recdata(7 downto 1);
end if;
end if;
end process;
-- Counter of data bits
COUNT8: process(resetn, clock)
begin
if (resetn = '0') then
cntval <= (others => '0');
elsif (clock'event and clock = '1') then
if (shift = '1') then
cntval <= cntval + 1;
end if;
end if;
end process;
zero <= not (cntval(0) or cntval(1) or cntval(2));
-- Parity check of received data
PARITY_CHECK: process(clock, parset)
begin
if (parset = '1') then
parbit <= '1';
elsif (clock'event and clock = '1') then
if (shift = '1' and ps2_dta = '1') then
parbit <= not parbit;
end if;
end if;
end process;
-- Synchronous process of control state machine
FSM_SYNC: process(clock, resetn)
begin
if (resetn = '0') then
c_state <= IDLE;
shift <= '0';
latch <= '0';
err <= '0';
parset <= '1';
elsif (clock'event and clock = '1') then
c_state <= n_state;
shift <= n_shift;
latch <= n_latch;
err <= n_err;
parset <= n_parset;
end if;
end process;
-- Combinatorial process of control state machine
FSM_COMB: process(c_state, ps2_dv, ps2_dta, zero)
begin
-- default values
n_shift <= '0';
n_latch <= '0';
n_err <= '0';
n_parset <= '0';
case c_state is
-- wait to receive data
when IDLE => if ((ps2_dv and (not ps2_dta)) = '1') then
n_state <= START;
n_parset <= '1';
else
n_state <= IDLE;
end if;
-- receive first data bit
when START => if (ps2_dv = '0') then
n_state <= START;
else
n_state <= DATA;
n_shift <= '1';
end if;
-- receive remaining data bits and parity
when DATA => if (ps2_dv = '0') then
n_state <= DATA;
elsif (zero = '0') then
n_state <= DATA;
n_shift <= '1';
else
n_state <= PARITY;
if (parbit /= ps2_dta) then
n_err <= '1';
end if;
end if;
-- receive stop bit
when PARITY => if (ps2_dv = '0') then
n_state <= PARITY;
else
n_state <= IDLE;
n_latch <= '1';
n_err <= not ps2_dta;
end if;
end case;
end process;
-- Output latch
LED_OUTPUTS: process(resetn, clock)
begin
if (resetn = '0') then
leds <= (others => '1');
elsif (clock'event and clock = '1') then
if (err = '1') then
leds <= (others => '1');
elsif (latch = '1') then
leds <= not recdata;
end if;
end if;
end process;
end behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -