Sistem modul keyboard driver seperti pada Gambar 1 dirancang berdasarkan timing diagram PS/2 port. Operasi modul keyboard driver ialah mengolah data bit tombol keyboard menjadi make code. Berdasarkan prinsip kerja keyboard driver tersebut maka perancangan sistem modul keyboard driver menggunkan proses sekuensial dengan model Moore. Jika tombol keyboard ditekan maka keyboard akan mengirimkan sinyal clock pada ps2_clk dan sinyal data pada ps2_dat. Setiap terjadinya falling edge ps2_clk maka counter atau cnt akan bertambah satu untuk menghitung jumlah ps2_clk dan register geser sinkron 11 bit akan tergeser ke kanan 1 bit dengan data ps2_dat. Jika tidak terjadinya falling edge pada ps2_clk maka nilai counter sama dengan nilai counter sebelumnya dan data register ps2_dat sama dengan data sebelumnya.

Gambar 1 Modul Keyboard Driver
Keterangan:
• clk = masukan sumber sinyal clock 25 MHz
• rst = masukan sinyal reset
• ps2_clk = masukan port PS/2 clock
• ps2_dat = masukan port PS/2 data
• code = keluaran sinyal code 8 bit
• busy = keluaran sinyal proses baca keyboard

Gambar 2 Timing diagram perancangan keyboard driver
Jika jumlah cnt > 0 dan cnt <= 11 maka busy akan ‘1’ seperti ditunjukan pada Gambar 2, sedangkan jika tidak maka busy akan ‘0’. Jika jumlah cnt = 11 dan keadaan ps2_clk ‘1’ maka nilai cnt kembali menjadi 0 dan hasil keluaran code diambil pada 8 bit register ps2_dat mulai dari bit ke-1 sampai bit ke-8 sebagai make code, command code atau break code.
VHDL Keyboard Driver PS/2 Spartan-3E:
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 15:05:00 10/13/2014
-- Design Name:
-- Module Name: keyboard_driver - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
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;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity keyboard_driver is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
ps2_clk : in STD_LOGIC;
ps2_dat : in STD_LOGIC;
busy : out STD_LOGIC;
port_code : out STD_LOGIC_VECTOR (7 downto 0);
code : out STD_LOGIC_VECTOR (7 downto 0));
end keyboard_driver;
architecture Behavioral of keyboard_driver is
--------------------------------------Signal Keyboard----------------------------------------------
signal ps2_clk_syn : STD_LOGIC;
signal busy_P, busy_N : STD_LOGIC := '0';
signal cnt_P, cnt_N : unsigned (3 downto 0) := (others => '0');
---------------------------------------------------------------------------------------------------
---------------------------------------Signal Register Data----------------------------------------
signal ps2_word_P, ps2_word_N : unsigned(10 downto 0) := (others => '0'); --lebar 11 bit ps2 data word --> start,D0-D7,parity,stop
signal code_P, code_N : unsigned (7 downto 0);
---------------------------------------------------------------------------------------------------
begin
process(clk, rst)
begin
if rst = '1' then
ps2_word_P <= (others => '0');
busy_P <= '0';
ps2_clk_syn <= '0';
code_P <= (others => '0');
cnt_P <= (others => '0');
elsif clk'event and clk = '1' then
ps2_clk_syn <= ps2_clk;
code_P <= code_N;
cnt_P <= cnt_N;
busy_P <= busy_N;
ps2_word_P <= ps2_word_N;
end if;
end process;
-----------------------------------Register Input Keyboard--------------------------------------
process(cnt_P, ps2_word_P, ps2_dat, ps2_clk_syn)
begin
if (ps2_clk_syn'event and ps2_clk_syn = '0') then --falling edge of PS2 clock
cnt_N <= cnt_P + 1;
ps2_word_N(10 downto 0) <= ps2_dat & ps2_word_P(10 downto 1); --shift in PS2 data bit
end if;
if cnt_P = 11 then
cnt_N <= (others => '0');
end if;
end process;
------------------------------------------------------------------------------------------------
---------------------------------Proses Pembacaan Data----------------------------------
process(cnt_P, busy_P, code_P, ps2_word_P)
begin
busy_N <= busy_P;
code_N <= code_P;
if cnt_P = 0 then
code_N <= code_P;
busy_N <= '0';
elsif cnt_P >= 1 and cnt_P <= 10 then
code_N <= code_P;
busy_N <= '1';
else
code_N <= ps2_word_P(8 downto 1);
busy_N <= '0';
end if;
end process;
-------------------------------------------------Output-------------------------------------------
busy <= STD_LOGIC(busy_P);
code <= STD_LOGIC_VECTOR(code_P);
port_code <= STD_LOGIC_VECTOR(code_P);
--------------------------------------------------------------------------------------------------
end Behavioral;
Gambar 1 Modul Keyboard Driver
Keterangan:
• clk = masukan sumber sinyal clock 25 MHz
• rst = masukan sinyal reset
• ps2_clk = masukan port PS/2 clock
• ps2_dat = masukan port PS/2 data
• code = keluaran sinyal code 8 bit
• busy = keluaran sinyal proses baca keyboard
Gambar 2 Timing diagram perancangan keyboard driver
Jika jumlah cnt > 0 dan cnt <= 11 maka busy akan ‘1’ seperti ditunjukan pada Gambar 2, sedangkan jika tidak maka busy akan ‘0’. Jika jumlah cnt = 11 dan keadaan ps2_clk ‘1’ maka nilai cnt kembali menjadi 0 dan hasil keluaran code diambil pada 8 bit register ps2_dat mulai dari bit ke-1 sampai bit ke-8 sebagai make code, command code atau break code.
VHDL Keyboard Driver PS/2 Spartan-3E:
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 15:05:00 10/13/2014
-- Design Name:
-- Module Name: keyboard_driver - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
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;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity keyboard_driver is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
ps2_clk : in STD_LOGIC;
ps2_dat : in STD_LOGIC;
busy : out STD_LOGIC;
port_code : out STD_LOGIC_VECTOR (7 downto 0);
code : out STD_LOGIC_VECTOR (7 downto 0));
end keyboard_driver;
architecture Behavioral of keyboard_driver is
--------------------------------------Signal Keyboard----------------------------------------------
signal ps2_clk_syn : STD_LOGIC;
signal busy_P, busy_N : STD_LOGIC := '0';
signal cnt_P, cnt_N : unsigned (3 downto 0) := (others => '0');
---------------------------------------------------------------------------------------------------
---------------------------------------Signal Register Data----------------------------------------
signal ps2_word_P, ps2_word_N : unsigned(10 downto 0) := (others => '0'); --lebar 11 bit ps2 data word --> start,D0-D7,parity,stop
signal code_P, code_N : unsigned (7 downto 0);
---------------------------------------------------------------------------------------------------
begin
process(clk, rst)
begin
if rst = '1' then
ps2_word_P <= (others => '0');
busy_P <= '0';
ps2_clk_syn <= '0';
code_P <= (others => '0');
cnt_P <= (others => '0');
elsif clk'event and clk = '1' then
ps2_clk_syn <= ps2_clk;
code_P <= code_N;
cnt_P <= cnt_N;
busy_P <= busy_N;
ps2_word_P <= ps2_word_N;
end if;
end process;
-----------------------------------Register Input Keyboard--------------------------------------
process(cnt_P, ps2_word_P, ps2_dat, ps2_clk_syn)
begin
if (ps2_clk_syn'event and ps2_clk_syn = '0') then --falling edge of PS2 clock
cnt_N <= cnt_P + 1;
ps2_word_N(10 downto 0) <= ps2_dat & ps2_word_P(10 downto 1); --shift in PS2 data bit
end if;
if cnt_P = 11 then
cnt_N <= (others => '0');
end if;
end process;
------------------------------------------------------------------------------------------------
---------------------------------Proses Pembacaan Data----------------------------------
process(cnt_P, busy_P, code_P, ps2_word_P)
begin
busy_N <= busy_P;
code_N <= code_P;
if cnt_P = 0 then
code_N <= code_P;
busy_N <= '0';
elsif cnt_P >= 1 and cnt_P <= 10 then
code_N <= code_P;
busy_N <= '1';
else
code_N <= ps2_word_P(8 downto 1);
busy_N <= '0';
end if;
end process;
-------------------------------------------------Output-------------------------------------------
busy <= STD_LOGIC(busy_P);
code <= STD_LOGIC_VECTOR(code_P);
port_code <= STD_LOGIC_VECTOR(code_P);
--------------------------------------------------------------------------------------------------
end Behavioral;
Tidak ada komentar:
Posting Komentar