- added
git-svn-id: http://moon:8086/svn/vhdl/trunk@1422 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- 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;
|
||||
Reference in New Issue
Block a user