Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

How the PS2 clock debounce is done in this VHDL code?

Status
Not open for further replies.

jshroff

Advanced Member level 4
Joined
Apr 30, 2004
Messages
115
Helped
14
Reputation
28
Reaction score
0
Trophy points
1,296
Activity points
935
Hi All,

I am attempting to learn VHDL using a digilent board and example and have a very basic question.

The code is ...


Code:
----------------------------------------------------------------------------------
-- Company: 		Digilent Inc.
-- Engineer: 		Claudia Goga
-- 
-- Create Date:    22:33:35 11/25/06 
-- Module Name:    PS2_Reader - Behavioral 
-- Target Devices: CoolRunner2 CPLD
-- Tool versions:  Xilinx ISE v7.1i 
-- Description: 
--		This module reads scan codes from the PS2 Port. Every time a 
--		new scan code is entirely received it enables the fRd signal for one
--		main clock period.
--
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity PS2_Reader is
    Port ( mclk  : in std_logic;                        -- System Clock 
	 		  PS2C : in std_logic;                         -- PS2 Clock
           PS2D : in std_logic;                         -- PS2 data
			  rst: in std_logic;                           -- Reset BTN0
			  Ps2Dout : out std_logic_vector(7 downto 0);  -- out data
           fRd : out std_logic);                        -- data valid flag
end PS2_Reader;

architecture Behavioral of PS2_Reader is

------------------------------------------------------------------------
--				 SIGNAL and CONSTANT DECLARATIONS
------------------------------------------------------------------------
--The constants below define state codes for the PS2 Keyboard 
--reader using ONE HOT encoding.

constant idle:         std_logic_vector (5 downto 0):="000000";
constant shift_data:   std_logic_vector (5 downto 0):="000001";
constant check_parity: std_logic_vector (5 downto 0):="000010";
constant check_stopbit:std_logic_vector (5 downto 0):="000100";
constant frame_error:  std_logic_vector (5 downto 0):="001000";
constant parity_error: std_logic_vector (5 downto 0):="010000";
constant end_char:     std_logic_vector (5 downto 0):="100000";

--state register and next state register for the FSM
signal state, next_state: std_logic_vector (5 downto 0):=idle;

signal D_PS2C: std_logic:='0';                     -- debounced PS2C
signal Q1, Q2: std_logic:='0';

--shift register; stores the received bits
signal REG: std_logic_vector(7 downto 0):=X"00";

signal ptysum: std_logic:='0';	                  -- parity sum
signal ptycheck: std_logic:='0';	                  -- parity check bit

signal cnt: integer range 0 to 7:=0;               -- counter

--The attributes below prevent the ISE compiler from 
--optimizing the state machines. The states will be implemented as 
--described in the constant declarations above.

attribute fsm_extract : string;
attribute fsm_extract of state: signal is "no"; 
attribute fsm_extract of next_state: signal is "no"; 

attribute fsm_encoding : string;
attribute fsm_encoding of state: signal is "user"; 
attribute fsm_encoding of next_state: signal is "user"; 

attribute signal_encoding : string;
attribute signal_encoding of state: signal is "user"; 
attribute signal_encoding of next_state: signal is "user";

begin

----------------------------------------------------------------------
--				 MODULE IMPLEMENTATION
----------------------------------------------------------------------

----------------- Sample Keyboard Inputs -----------------------------

debounce: process (mclk, PS2C, Q1, Q2)
begin
	if mclk'event and mclk='1' then
		 Q1<=PS2C;
		 Q2<=Q1;
	end if;
end process debounce;

D_PS2C<= (NOT Q1) and Q2;

----------------- Synchronization Process ----------------------------

regstate: process (mclk, next_state, rst)
begin
	if rst='1' then
			 state<=idle;	                     -- state machine reset
	elsif mclk'EVENT and mclk='1' then
			 state<=next_state;
	end if;
end process regstate;

-------------------- State Transitions -------------------------------

transition: process (state, D_PS2C, PS2D, cnt, ptycheck)
begin
case state is
	when idle=>-- idle
		if D_PS2C='1' and PS2D='0' then        -- check start bit
			 next_state<=shift_data;
		else
			 next_state<=idle;
		end if;

	when shift_data=>                         -- shift in data
		if D_PS2C='1' and cnt=7 then
			 next_state<=check_parity;          -- go and check parity
		else
			 next_state<=shift_data;
		end if;

	when check_parity=>                       -- check parity
		if D_PS2C='1' and PS2D=ptycheck then
			 next_state<=check_stopbit;         -- valid parity bit 
			 									         -- go and check stopbit
		elsif D_PS2C='1' then
			 next_state<=parity_error;          -- parity error
		else
			 next_state<=check_parity;
		end if;

	when check_stopbit=>                      -- check stopbit;
		if D_PS2C='1' and PS2D='1' then
			 next_state<=end_char;              -- valid stopbit, end Char
		elsif D_PS2C='1' then
			 next_state<=frame_error;           -- Frame Error
		else
			 next_state<=check_stopbit;
		end if;

	when frame_error=>                        -- Frame Error	
		next_state<=idle;

	when parity_error=>                       -- Parity Error
		next_state<=idle;  

	when end_char=>                           -- end Char
		next_state<=idle;

	when others => next_state<=idle;
end case;
end process transition;


------Counting bits and registering when state=shift_data--------------- 

regin: process (mclk, D_PS2C, PS2D, cnt, ptysum, state)
begin
if state/=shift_data then 
		cnt<=0;
		ptysum<='0';
elsif mclk'EVENT and mclk='1' then
	if D_PS2C='1' then
		ptysum<=ptysum XOR PS2D;                 -- calculating the parity sum
		REG(7 downto 0)<=PS2D&REG(7 downto 1);   -- shifting data into register
														      
		if cnt=7 then
			cnt<=0;
		else
			cnt<=cnt+1;
		end if;
	end if;
end if;
end process regin;

------------------PARITIY SUM-------------------------------------------

parity_sum: process (mclk, D_PS2C, PS2D, cnt, state, ptysum)
begin
if mclk'EVENT and mclk='1' then
	if state=shift_data and D_PS2C='1' and cnt=7 then
			ptycheck<=(NOT ptysum) XOR PS2D;       --parity check bit
	end if;
end if;
end process parity_sum; 

----------------OUTPUT ASSIGNEMENT--------------------------------------

Ps2Dout<=REG;
fRd<='1' when state=end_char else '0';

end Behavioral;

I am confused on how the PS2 clock debounce is done. They way I read it

Since Q2 is assigned the value of Q1 how would (Not Q1) and Q2 every take on the value of 1?

Thanks
Jay
 

vhdl idle state

Hello,

this is a synchronous edge detection (falling_edge in this case). You must regard signal assignments in a clock synchronous sequential process as instantiation of flipflops, the result takes effect in the next clock cycle. Thus Q1 represents the present value of PS2C, Q2 the previous value.

The expression (NOT Q1) and Q2 is true for one clock cycle at PS2C falling edge, when Q1 is already '0' and Q2 still '1'. This way you create an event from PS2C falling_edge, but synchronized to mclk, which is helpful to process PS2 data in mclk domain.

Regards,
Frank
 

ps2 scancodes in vhdl

For someone just getting into VHDL dont you think that this is a bit over your head? Im not saying you cant do it but your frustration level will be much less if you try code/functions that are bit more inline with learning the ins and outs of VHDL.

If you are looking for a great tutorial method try the Cypress Warp kit. Comes with a VHDL book and software.

E
 

ps2 vhdl code

refers to synchronizers theory if you are really interested ..
it is given good in
digital design by john wakerly.
or else just google how to manage async signal in synchronous domain
refer to following ppt
 

Asking for help..
i need help for FPGA xylink spartan 3A with VHDL language

my project is to connect PS2 keyboard to xylinx spartan 3 (XC3S700AN)

would u like to give me some simple examples about my project :eek:

btw i use Xilinx ISE Design Suite 12.4 :D

sorry for this noob question :eek:
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top