Files
vhdl/projects/ps2if/src/ps2_core.bak.vhd
T
jens 5309734167 - added
git-svn-id: http://moon:8086/svn/vhdl/trunk@1422 cc03376c-175c-47c8-b038-4cd826a8556b
2021-03-21 11:25:09 +00:00

241 lines
5.6 KiB
VHDL

--------------------------------------------------------------------------------
-- 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;