PS2 interface with FPGA Development Kit
PC mouse and the keyboard use the two-wire PS/2 serial bus to communicate with a host device.
6-pin Mini-DIN (PS/2):
☞1 – Data
☞2 – Not Implemented
☞3 – Ground
☞4 – Vcc (+5V)
☞5 – Clock
☞6 – Not Implemented
Interfacing PS/2 with FPGA Development Kit
The FPGA Development Kit includes PS/2 port for mouse/keyboard interface and it is the standard 6-pin mini-DIN connector. Only pins 1 and 5 of the connector attach to the FPGA I/O lines.
PS2 Placement in FPGA Development Kit
The Data and Clock lines are both open-collector with pullup resistors to Vcc. An “open-collector” interface has two possible state: low, or high impedance. In the “low” state, a transistor pulls the line to ground level. In the “high impedance” state, the interface acts as an open circuit and doesn’t drive the line low or high.
Furthermore, a “pullup” resistor is connected between the bus and Vcc so the bus is pulled high if none of the devices on the bus are actively pulling it low.
The PS/2 mouse and keyboard implement a bidirectional synchronous serial protocol. The bus is “idle” when both lines are high (open-collector). This is the only state where the keyboard/ mouse is allowed begin transmitting data. The host has ultimate control over the bus and may inhibit communication at any time by pulling the Clock line low.
The device always generates the clock signal. If the host wants to send data, it must first inhibit communication from the device by pulling Clock low. The host then pulls Data low and releases Clock. This is the “Request-to-Send” state and signals the device to start generating clock pulses.
All data is transmitted one byte at a time and each byte is sent in a frame consisting of 11-12 bits. These bits are:
☞1 start bit. This is always 0.
☞8 data bits, least significant bit first.
☞1 parity bit (odd parity).
☞1 stop bit. This is always 1.
☞1 acknowledge bit (host-to-device communication only)
The parity bit is set if there is an even number of 1’s in the data bits and reset (0) if there is an odd number of 1’s in the data bits. The number of 1’s in the data bits plus the parity bit always add up to an odd number (odd parity.) This is used for error detection. The keyboard/mouse must check this bit and if incorrect it should respond as if it had received an invalid command.
Data sent from the device to the host is read on the falling edge of the clock signal; data sent from the host to the device is read on the rising edge. The clock frequency must be in the range 10 – 16.7 kHz. This means clock must be high for 30 – 50 microseconds and low for 30 – 50 microseconds.. If you’re designing a keyboard, mouse, or host emulator, you should modify/sample the Data line in the middle of each cell. I.e. 15 – 25 microseconds after the appropriate clock transition. Again, the keyboard/mouse always generates the clock signal, but the host always has ultimate control over communication.
VHDL Code Description for PS2 Interface
The data send from PS2 keyboard received serially and stored in the array. The corresponding ascii value will be displayed in the LED’s
VHDL Code for PS2 interface with
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity key is port( data: in std_logic; --scan data from keyboard pclk: in std_logic; --clk input for keyboard l1 : out std_logic; --data display l2 : out std_logic; l3 : out std_logic; l4 : out std_logic; l5 : out std_logic; l6 : out std_logic; l7 : out std_logic; l8 : out std_logic); end key; architecture Behavioral of key is type state is (state1,state2,state3,state4,state5,state6,state7,state8,state9,state10); signal ps,ns : state; signal store : std_logic_vector(9 downto 0); begin process(pclk,data) begin if pclk'event and pclk = '1' then ps <= ns; --increment of data bit & state end if; if pclk'event and pclk = '0' then if ps = state1 then store(0) <= data; --ascii data storage ns <= state2; elsif ps = state2 then store(1) <= data; ns <= state3; elsif ps = state3 then store(2) <= data; ns <= state4; elsif ps = state4 then store(3) <= data; ns <= state5; elsif ps = state5 then store(4) <= data; ns <= state6; elsif ps = state6 then store(5) <= data; ns <= state7; elsif ps = state7 then store(6) <= data; ns <= state8; elsif ps = state8 then store(7) <= data; ns <= state9; elsif ps = state9 then store(8) <= data; ns <= state10; elsif ps = state10 then store(9) <= data; ns <= state1; end if; end if; end process; process(store) begin l1 <= store(1); --stored ascii data display l2 <= store(2); l3 <= store(3); l4 <= store(4); l5 <= store(5); l6 <= store(6); l7 <= store(7); l8 <= store(8); end process; end Behavioral;
net data loc="p28"; net pclk loc="p29"; NET "pclk" CLOCK_DEDICATED_ROUTE = FALSE; net l1 loc="p36"; net l2 loc="p37"; net l3 loc="p39"; net l4 loc="p40"; net l5 loc="p42"; net l6 loc="p43"; net l7 loc="p44"; net l8 loc="p45";