-------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 18:05:41 10/22/05 -- Design Name: -- Module Name: ps2_core - Behavioral -- Project Name: -- Target Device: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- 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; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity ps2_core is Generic (f_sys_clk : real := 100.0); Port ( rst : in std_logic; clk : in std_logic; ce : in std_logic; d_in : in std_logic_vector(7 downto 0); d_out : out std_logic_vector(7 downto 0); rdy_in : out std_logic; rdy_out : out std_logic; write_en : in std_logic; read_en : in std_logic; ps2_clk : in std_logic; ps2_data : in std_logic); end ps2_core; architecture Behavioral of ps2_core is COMPONENT prescaler GENERIC (divide : integer); PORT( rst : IN std_logic; clk : IN std_logic; ce : IN std_logic; rdy : OUT std_logic ); END COMPONENT; COMPONENT timeout_counter GENERIC (N : integer); PORT( rst : IN std_logic; clk : IN std_logic; ce : IN std_logic; load : IN integer range 0 to N-1; load_en : IN std_logic; rdy : OUT std_logic ); END COMPONENT; COMPONENT sipo GENERIC (N : integer); PORT( rst : IN std_logic; clk : IN std_logic; ce : IN std_logic; d_in : IN std_logic; d_out : OUT std_logic_vector(7 downto 0) ); END COMPONENT; COMPONENT oneshot GENERIC (mode : integer); PORT( rst : IN std_logic; clk : IN std_logic; input : IN std_logic; output : OUT std_logic ); END COMPONENT; -- Types type read_state_t is (read_start_st, read_data_st, read_parity_st, read_stop_st); -- Constant constant prescaler_us : integer := integer(f_sys_clk); constant timeout_us : integer := 1000; -- Signals signal en_us : std_logic; signal timeout_load_en : std_logic; signal timeout_flag : std_logic; signal read_cs : read_state_t; signal read_ns : read_state_t; signal data_cnt_en : std_logic; signal data_cnt : integer range 0 to 7; signal sipo_en : std_logic; signal data_rdy : std_logic; signal out_reg_ce : std_logic; signal sipo_reg : std_logic_vector(7 downto 0); begin Inst_prescaler: prescaler GENERIC MAP ( divide => prescaler_us) PORT MAP( rst => rst, clk => clk, ce => ce, rdy => en_us ); Inst_timeout_counter: timeout_counter GENERIC MAP ( N => timeout_us) PORT MAP( rst => rst, clk => clk, ce => en_us, load => timeout_us - 1, load_en => timeout_load_en, rdy => timeout_flag ); Inst_sipo: sipo GENERIC MAP ( N => 8) PORT MAP( rst => rst, clk => ps2_clk, ce => sipo_en, d_in => ps2_data, d_out => sipo_reg ); Inst_oneshot: oneshot GENERIC MAP ( mode => 1) PORT MAP( rst => rst, clk => clk, input => data_rdy, output => out_reg_ce ); ------------------------------------------- out_reg: process(rst, clk, out_reg_ce, read_en) begin if rst = '1' then d_out <= (others => '0'); rdy_out <= '0'; elsif rising_edge(clk) then if out_reg_ce = '1' then d_out <= sipo_reg; rdy_out <= '1'; elsif read_en = '1' then rdy_out <= '0'; end if; end if; end process; read_state_clk: process(rst, ps2_clk) begin if rst = '1' then read_cs <= read_start_st; else if falling_edge(ps2_clk) then read_cs <= read_ns; if (data_cnt_en = '1') then if (data_cnt /= 0) then data_cnt <= data_cnt - 1; end if; else data_cnt <= 7; end if; end if; end if; end process; read_state_output: process(read_cs) begin timeout_load_en <= '0'; data_cnt_en <= '0'; rdy_in <= '0'; sipo_en <= '0'; data_rdy <= '0'; -- rdy_out <= '0'; case (read_cs) is when read_start_st => data_rdy <= '1'; timeout_load_en <= '1'; -- rdy_out <= '1'; when read_data_st => sipo_en <= '1'; data_cnt_en <= '1'; when others => null; end case; end process; read_state_decode: process (read_cs, timeout_flag, data_cnt, ps2_data) begin --declare default state for next_state to avoid latches read_ns <= read_cs; --default is to stay in current state --insert statements to decode next_state --below is a simple example case (read_cs) is when read_start_st => if ps2_data = '0' then read_ns <= read_data_st; end if; when read_data_st => if timeout_flag = '1' then read_ns <= read_start_st; elsif data_cnt = 0 then read_ns <= read_parity_st; end if; when read_parity_st => read_ns <= read_stop_st; if timeout_flag = '1' then read_ns <= read_start_st; end if; when read_stop_st => read_ns <= read_start_st; when others => read_ns <= read_start_st; end case; end process; end Behavioral;