Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
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