Sei sulla pagina 1di 3

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
ENTITY ps2_keyboard IS
GENERIC (
deb_cycles: INTEGER := 200; --4us for debouncer (@50 MHz)
idle_cycles: INTEGER := 3000); --60us (>1/2 period ps2_clk)
PORT (
clk: IN BIT; --system clock (50 MHz)
ps2clk: IN BIT; --clk from keyboard (10 17 kHz)
ps2data: IN BIT; --data from keyboard
ssd: OUT BIT_VECTOR(6 DOWNTO 0));--data out to SSD
END ps2_keyboard;
---------------------------------------------------------------------ARCHITECTURE ps2_keyboard OF ps2_keyboard IS
SIGNAL deb_ps2clk: BIT; --debounced ps2_clk
SIGNAL deb_ps2data: BIT; --debounced ps2_data
SIGNAL data, dout: BIT_VECTOR(10 DOWNTO 0);
SIGNAL idle: BIT; --'1' means data line is idle
SIGNAL error: BIT; --'1' when start, stop, or parity wrong
BEGIN
---------Debouncer for ps2clk:--------------PROCESS (clk)
VARIABLE count: INTEGER RANGE 0 TO deb_cycles;
BEGIN
IF (clk'EVENT AND clk='1') THEN
IF (deb_ps2clk=ps2clk) THEN
count := 0;
ELSE
count := count + 1;
IF (count=deb_cycles) THEN
--VHDL Design of Serial Communications Circuits 385
deb_ps2clk <= ps2clk;
count := 0;
END IF;
END IF;
END IF;
END PROCESS;
---------Debouncer for ps2data:-------------PROCESS (clk)
VARIABLE count: INTEGER RANGE 0 TO deb_cycles;
BEGIN
IF (clk'EVENT AND clk='1') THEN
IF (deb_ps2data=ps2data) THEN
count := 0;
ELSE
count := count + 1;
IF (count=deb_cycles) THEN
deb_ps2data <= ps2data;
count := 0;
END IF;

END IF;
END IF;
END PROCESS;
---------Detection of idle state:----------PROCESS (clk)
VARIABLE count: INTEGER RANGE 0 TO idle_cycles;
BEGIN
IF (clk'EVENT AND clk='0') THEN
IF (deb_ps2data='0') THEN
idle <= '0';
count := 0;
ELSIF (deb_ps2clk='1') THEN
count := count + 1;
IF (count=idle_cycles) THEN
idle <= '1';
END IF;
ELSE
count := 0;
END IF;
END IF;
END PROCESS;
---------Receiving data from keyboard:------PROCESS (deb_ps2clk)
VARIABLE i: INTEGER RANGE 0 TO 15;
-- Chapter 14
BEGIN
IF (deb_ps2clk'EVENT AND deb_ps2clk='0') THEN
IF (idle='1') THEN
i:=0;
ELSE
data(i) <= deb_ps2data;
i := i + 1;
IF (i=11) THEN
i:=0;
dout <= data;
END IF;
END IF;
END IF;
END PROCESS;
---------Checking for errors:---------------PROCESS (dout)
BEGIN
IF (dout(0)='0' AND dout(10)='1' AND (dout(1) XOR
dout(2) XOR dout(3) XOR dout(4) XOR dout(5)
XOR dout(6) XOR dout(7) XOR dout(8)
XOR dout(9))='1') THEN
error <= '0';
ELSE
error <= '1';
END IF;
END PROCESS;
---------SSD driver:--------------------------This process is a MAKE-code to SSD-code conversion.
--No need to store "ssd" because "dout" is already registered.
PROCESS (dout, error)
BEGIN
IF (error='0') THEN
CASE dout(8 DOWNTO 1) IS
WHEN "01000101" => ssd <= "0000001"; --"0" on SSD
WHEN "00010110" => ssd <= "1001111"; --"1" on SSD

WHEN "00011110" => ssd <= "0010010"; --"2" on SSD


WHEN "00100110" => ssd <= "0000110"; --"3" on SSD
WHEN "00100101" => ssd <= "1001100"; --"4" on SSD
WHEN "00101110" => ssd <= "0100100"; --"5" on SSD
WHEN "00110110" => ssd <= "0100000"; --"6" on SSD
WHEN "00111101" => ssd <= "0001111"; --"7" on SSD
WHEN "00111110" => ssd <= "0000000"; --"8" on SSD
WHEN "01000110" => ssd <= "0000100"; --"9" on SSD
--VHDL Design of Serial Communications Circuits 387
WHEN "11110000" => ssd <= "1111111"; -- blank
WHEN OTHERS => ssd <= "0010000"; --"e" on SSD
END CASE;
ELSE
ssd <= "0110000"; --"E" on SSD
END IF;
END PROCESS;
END ps2_keyboard;

Potrebbero piacerti anche