Initial version

Committed on the Free edition of March Hare Software CVSNT Server.
Upgrade to CVS Suite for more features and support:
http://march-hare.com/cvsnt/


git-svn-id: http://moon:8086/svn/vhdl/trunk@621 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2009-11-06 15:29:54 +00:00
parent 646e49e5b9
commit 012623b603
7 changed files with 1275 additions and 0 deletions
+89
View File
@@ -0,0 +1,89 @@
--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 19:34:24 10/23/05
-- Design Name:
-- Module Name: debounce - 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 debounce is
Generic ( ncyc_latency : integer := 100);
Port ( rst : in std_logic;
clk : in std_logic;
input : in std_logic;
output : out std_logic);
end debounce;
architecture Behavioral of debounce is
type debounce_state_t is (init_st, wait_st, rel_st);
signal debounce_cs : debounce_state_t;
signal debounce_ns : debounce_state_t;
signal count : integer range 0 to ncyc_latency-1;
signal input_last : std_logic;
begin
debounce_clk: process(rst, clk, debounce_ns, debounce_cs, input)
begin
if (rst = '1') then
count <= 0;
output <= input;
input_last <= input;
else
if rising_edge(clk) then
debounce_cs <= debounce_ns;
if (debounce_cs = wait_st) then
if (count /= 0) then
count <= count - 1;
end if;
else
count <= ncyc_latency-1;
if (debounce_cs = rel_st) then
output <= input;
input_last <= input;
end if;
end if;
end if;
end if;
end process;
debounce_in: process(rst, clk, input, input_last, debounce_cs, count)
begin
debounce_ns <= debounce_cs;
case debounce_cs is
when init_st =>
if (input /= input_last) then
debounce_ns <= wait_st;
end if;
when wait_st =>
if (count = 0) then
debounce_ns <= rel_st;
end if;
when others =>
debounce_ns <= init_st;
end case;
end process;
end Behavioral;
+592
View File
@@ -0,0 +1,592 @@
--------------------------------------------------------------------------------
-- 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.NUMERIC_STD.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_hz : integer := 100E6
);
Port
(
rst : in std_logic;
clk : in std_logic;
din : in unsigned(7 downto 0);
dout : out unsigned(7 downto 0);
tx_empty : out std_logic;
rx_present : out std_logic;
din_vld : in std_logic;
read_en : in std_logic;
ps2_clk_rx : in std_logic;
ps2_data_rx : in std_logic;
ps2_clk_tx : out std_logic;
ps2_data_tx : out std_logic
);
end ps2_core;
architecture Behavioral of ps2_core is
-- Types
type line_state_rx_t is (start_wait_st, start_trans_st, start_sample_st,
data_wait_st, data_trans_st, data_sample_st,
parity_wait_st, parity_trans_st, parity_sample_st,
stop_wait_st, stop_trans_st, stop_sample_st,
valid_st);
type line_state_tx_t is (tx_idle_st, tx_clock_assert_st, tx_start_latency_st,
tx_start_assert_st, tx_clock_release_st, tx_dev_trans_st,
tx_data_wait_st, tx_data_trans_st, tx_data_sample_st,
tx_parity_update_st, tx_dev_wait_st,
tx_parity_wait_st, tx_parity_trans_st, tx_parity_sample_st,
tx_stop_wait_st, tx_stop_trans_st, tx_stop_sample_st,
tx_ack_trans_st, tx_ack_sample_st, tx_valid_st);
-- Constant
constant prescaler_us : integer := f_sys_clk_hz/1E6;
constant timeout_us : integer := 15000;
constant time_clock_assert : integer := 120;
-- Signals
signal en_us : std_logic;
signal timeout_rx_load_en : std_logic;
signal timeout_rx_en : std_logic;
signal timeout_rx_flag : std_logic;
signal timeout_tx_load_en : std_logic;
signal timeout_tx_en : std_logic;
signal timeout_tx_flag : std_logic;
signal read_cs : line_state_rx_t;
signal read_ns : line_state_rx_t;
signal write_cs : line_state_tx_t;
signal write_ns : line_state_tx_t;
signal data_cnt_en : std_logic;
signal data_cnt_rst : std_logic;
signal data_cnt : integer range 0 to 7;
signal data_cnt_tx_en : std_logic;
signal data_cnt_tx_rst : std_logic;
signal data_cnt_tx : integer range 0 to 7;
signal sipo_en : std_logic;
signal piso_en : std_logic;
signal piso_out : std_logic;
signal piso_load_en : std_logic;
signal rx_en : std_logic;
signal tx_en : std_logic;
signal rx_busy : std_logic;
signal tx_busy : std_logic;
signal rx_rdy : std_logic;
signal tx_rdy : std_logic;
signal tx_req : std_logic;
signal rx_reg : unsigned(7 downto 0);
signal tx_reg : unsigned(7 downto 0);
signal parity_rst : std_logic;
signal parity_en : std_logic;
signal parity : std_logic;
signal parity_tx_rst : std_logic;
signal parity_tx_en : std_logic;
signal parity_tx : std_logic;
signal timeout_count_rx : integer range 0 to timeout_us-1;
signal timeout_count_tx : integer range 0 to timeout_us-1;
signal timeval_tx : integer range 0 to timeout_us-1;
signal sipo_reg : unsigned(7 downto 0);
signal piso_reg : unsigned(7 downto 0);
begin
proc_prescaler:
process(clk)
variable cnt_prescaler : integer range 0 to prescaler_us-1;
begin
if rising_edge(clk) then
if rst = '1' then
cnt_prescaler := prescaler_us - 1;
en_us <= '0';
elsif cnt_prescaler = 0 then
cnt_prescaler := prescaler_us - 1;
en_us <= '1';
else
cnt_prescaler := cnt_prescaler - 1;
en_us <= '0';
end if;
end if;
end process proc_prescaler;
proc_timeout_counter_rx:
process (clk)
begin
if rising_edge(clk) then
if timeout_rx_load_en ='1' then
timeout_count_rx <= timeout_us - 1;
timeout_rx_flag <= '0';
else
if (timeout_count_rx /= 0) then
if timeout_rx_en ='1' then
timeout_count_rx <= timeout_count_rx - 1;
end if;
else
timeout_rx_flag <= '1';
end if;
end if;
end if;
end process;
proc_timeout_counter_tx:
process (clk)
begin
if rising_edge(clk) then
if timeout_tx_load_en ='1' then
timeout_count_tx <= timeval_tx;
timeout_tx_flag <= '0';
else
if (timeout_count_tx /= 0) then
if timeout_tx_en ='1' then
timeout_count_tx <= timeout_count_tx - 1;
end if;
else
timeout_tx_flag <= '1';
end if;
end if;
end if;
end process;
proc_rx_sipo:
process (clk)
begin
if rising_edge(clk) then
if (rst = '1') then
sipo_reg <= (others => '0');
elsif sipo_en = '1' then
sipo_reg <= ps2_data_rx & sipo_reg(sipo_reg'left downto 1);
end if;
end if;
rx_reg <= sipo_reg;
end process;
proc_tx_piso:
process (clk)
begin
if rising_edge(clk) then
if rst ='1' then
piso_reg <= (others => '0');
elsif piso_load_en = '1' then
piso_reg <= tx_reg;
elsif piso_en = '1' then
piso_reg <= '0' & piso_reg(piso_reg'left downto 1);
end if;
end if;
piso_out <= piso_reg(0);
end process;
proc_parity_bitser_rx:
process (clk)
begin
if rising_edge(clk) then
if parity_rst='1' then
parity <= '1';
elsif parity_en = '1' and ps2_data_rx = '1' then
parity <= not parity;
end if;
end if;
end process;
proc_parity_bitser_tx:
process (clk)
begin
if rising_edge(clk) then
if parity_tx_rst='1' then
parity_tx <= '1';
elsif parity_tx_en = '1' and piso_out = '1' then
parity_tx <= not parity_tx;
end if;
end if;
end process;
-------------------------------------------
tx_en <= tx_req and (not rx_busy);
rx_en <= not tx_busy;
-------------------------------------------
proc_out_reg:
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
dout <= (others => '0');
rx_present <= '0';
elsif rx_rdy = '1' then
dout <= rx_reg;
rx_present <= '1';
elsif read_en = '1' then
rx_present <= '0';
end if;
end if;
end process;
proc_in_reg:
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
tx_empty <= '1';
tx_req <= '0';
elsif piso_load_en = '1' then
tx_reg <= din;
tx_empty <= '1';
tx_req <= '0';
elsif din_vld = '1' then
tx_empty <= '0';
tx_req <= '1';
end if;
end if;
end process;
-------------------------------------------
proc_read_state_clk:
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
read_cs <= start_wait_st;
else
read_cs <= read_ns;
if (data_cnt_rst = '1') then
data_cnt <= 7;
elsif (data_cnt_en = '1') then
if (data_cnt /= 0) then
data_cnt <= data_cnt - 1;
end if;
end if;
end if;
end if;
end process;
-------------------------------------------
proc_write_state_clk:
process(rst, clk)
begin
if rising_edge(clk) then
if rst = '1' then
write_cs <= tx_idle_st;
else
write_cs <= write_ns;
if (data_cnt_tx_rst = '1') then
data_cnt_tx <= 7;
elsif (data_cnt_tx_en = '1') then
if (data_cnt_tx /= 0) then
data_cnt_tx <= data_cnt_tx - 1;
end if;
end if;
end if;
end if;
end process;
-------------------------------------------
read_state_output:
process(read_cs, en_us)
begin
timeout_rx_load_en <= '0';
timeout_rx_en <= en_us;
data_cnt_en <= '0';
data_cnt_rst <= '0';
sipo_en <= '0';
rx_rdy <= '0';
parity_en <= '0';
parity_rst <= '0';
rx_busy <= '1';
case (read_cs) is
when start_wait_st =>
timeout_rx_load_en <= '1';
timeout_rx_en <= '0';
rx_busy <= '0';
when start_sample_st =>
data_cnt_rst <= '1';
parity_rst <= '1';
timeout_rx_load_en <= '1';
when data_sample_st =>
data_cnt_en <= '1';
parity_en <= '1';
sipo_en <= '1';
timeout_rx_load_en <= '1';
when parity_sample_st =>
timeout_rx_load_en <= '1';
parity_en <= '1';
when valid_st =>
rx_busy <= '0';
rx_rdy <= '1';
when others => null;
end case;
end process;
read_state_decode:
process (read_cs, timeout_rx_flag, rx_en, data_cnt, ps2_data_rx, ps2_clk_rx)
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 start_wait_st =>
if ps2_data_rx = '0' and ps2_clk_rx = '1' and rx_en = '1' then
read_ns <= start_trans_st;
end if;
when start_trans_st =>
if timeout_rx_flag = '1' then
read_ns <= start_wait_st;
elsif ps2_data_rx = '0' and ps2_clk_rx = '0' then
read_ns <= start_sample_st;
end if;
when start_sample_st =>
read_ns <= data_wait_st;
-- Wait data change
when data_wait_st =>
if timeout_rx_flag = '1' then
read_ns <= start_wait_st;
elsif ps2_clk_rx = '1' then
read_ns <= data_trans_st;
end if;
-- Wait data trans
when data_trans_st =>
if timeout_rx_flag = '1' then
read_ns <= start_wait_st;
elsif ps2_clk_rx = '0' then
read_ns <= data_sample_st;
end if;
-- Data sample
when data_sample_st =>
read_ns <= data_wait_st;
if data_cnt = 0 then
read_ns <= parity_wait_st;
end if;
when parity_wait_st =>
if timeout_rx_flag = '1' then
read_ns <= start_wait_st;
elsif ps2_clk_rx = '1' then
read_ns <= parity_trans_st;
end if;
when parity_trans_st =>
if timeout_rx_flag = '1' then
read_ns <= start_wait_st;
elsif ps2_clk_rx = '0' then
read_ns <= parity_sample_st;
end if;
when parity_sample_st =>
read_ns <= stop_wait_st;
when stop_wait_st =>
if timeout_rx_flag = '1' then
read_ns <= start_wait_st;
elsif ps2_clk_rx = '1' then
read_ns <= stop_trans_st;
end if;
when stop_trans_st =>
if timeout_rx_flag = '1' then
read_ns <= start_wait_st;
elsif ps2_clk_rx = '0' and ps2_data_rx = '1' then
read_ns <= stop_sample_st;
end if;
when stop_sample_st =>
if timeout_rx_flag = '1' then
read_ns <= start_wait_st;
elsif ps2_clk_rx = '1' then
read_ns <= valid_st;
end if;
when valid_st =>
read_ns <= start_wait_st;
when others =>
read_ns <= start_wait_st;
end case;
end process;
-------------------------------------------
write_state_output:
process(write_cs, en_us, piso_out, parity_tx)
begin
timeout_tx_load_en <= '0';
timeout_tx_en <= en_us;
tx_rdy <= '0';
tx_busy <= '1';
piso_load_en <= '0';
ps2_clk_tx <= '1';
ps2_data_tx <= '1';
piso_en <= '0';
timeval_tx <= time_clock_assert - 1;
data_cnt_tx_en <= '0';
data_cnt_tx_rst <= '0';
parity_tx_rst <= '0';
parity_tx_en <= '0';
case (write_cs) is
when tx_idle_st =>
tx_busy <= '0';
timeout_tx_load_en <= '1';
timeout_tx_en <= '0';
when tx_clock_assert_st =>
parity_tx_rst <= '1';
piso_load_en <= '1';
data_cnt_tx_rst <= '1';
ps2_clk_tx <= '0';
when tx_start_assert_st =>
ps2_clk_tx <= '0';
ps2_data_tx <= '0';
when tx_clock_release_st =>
ps2_data_tx <= '0';
timeout_tx_load_en <= '1';
timeval_tx <= timeout_us - 1;
when tx_dev_wait_st =>
ps2_data_tx <= '0';
when tx_dev_trans_st =>
ps2_data_tx <= '0';
timeout_tx_load_en <= '1';
timeval_tx <= timeout_us - 1;
when tx_data_wait_st =>
ps2_data_tx <= piso_out;
when tx_data_trans_st =>
data_cnt_tx_en <= '1';
ps2_data_tx <= piso_out;
piso_en <= '1';
timeout_tx_load_en <= '1';
timeval_tx <= timeout_us - 1;
parity_tx_en <= '1';
when tx_data_sample_st =>
ps2_data_tx <= piso_out;
when tx_parity_update_st =>
parity_tx_en <= '1';
ps2_data_tx <= piso_out;
when tx_parity_sample_st =>
ps2_data_tx <= parity_tx;
when tx_parity_wait_st =>
ps2_data_tx <= parity_tx;
when tx_parity_trans_st =>
ps2_data_tx <= piso_out;
timeout_tx_load_en <= '1';
timeval_tx <= timeout_us - 1;
when tx_valid_st =>
tx_rdy <= '1';
when others => null;
end case;
end process;
write_state_decode:
process (write_cs, tx_en, data_cnt_tx, timeout_tx_flag, ps2_data_rx, ps2_clk_rx)
begin
--declare default state for next_state to avoid latches
write_ns <= write_cs; --default is to stay in current state
--insert statements to decode next_state
--below is a simple example
case (write_cs) is
when tx_idle_st =>
if tx_en = '1' then
write_ns <= tx_clock_assert_st;
end if;
when tx_clock_assert_st =>
if timeout_tx_flag = '1' then
write_ns <= tx_start_assert_st;
end if;
when tx_start_assert_st =>
write_ns <= tx_clock_release_st;
when tx_clock_release_st =>
write_ns <= tx_dev_wait_st;
when tx_dev_wait_st =>
if timeout_tx_flag = '1' then
write_ns <= tx_idle_st;
elsif ps2_clk_rx = '1' then
write_ns <= tx_dev_trans_st;
end if;
when tx_dev_trans_st =>
if timeout_tx_flag = '1' then
write_ns <= tx_idle_st;
elsif ps2_clk_rx = '0' then
write_ns <= tx_data_wait_st;
end if;
when tx_data_wait_st =>
if timeout_tx_flag = '1' then
write_ns <= tx_idle_st;
elsif ps2_clk_rx = '1' then
write_ns <= tx_data_sample_st;
end if;
when tx_data_sample_st =>
if timeout_tx_flag = '1' then
write_ns <= tx_idle_st;
elsif ps2_clk_rx = '0' then
write_ns <= tx_data_trans_st;
if (data_cnt_tx = 0) then
write_ns <= tx_parity_update_st;
end if;
end if;
when tx_data_trans_st =>
write_ns <= tx_data_wait_st;
when tx_parity_update_st =>
write_ns <= tx_parity_trans_st;
when tx_parity_trans_st =>
write_ns <= tx_parity_wait_st;
when tx_parity_wait_st =>
if timeout_tx_flag = '1' then
write_ns <= tx_idle_st;
elsif ps2_clk_rx = '1' then
write_ns <= tx_parity_sample_st;
end if;
when tx_parity_sample_st =>
if timeout_tx_flag = '1' then
write_ns <= tx_idle_st;
elsif ps2_clk_rx = '0' then
write_ns <= tx_stop_trans_st;
end if;
when tx_stop_trans_st =>
write_ns <= tx_stop_wait_st;
when tx_stop_wait_st =>
if timeout_tx_flag = '1' then
write_ns <= tx_idle_st;
elsif ps2_clk_rx = '1' then
write_ns <= tx_ack_trans_st;
end if;
when tx_ack_trans_st =>
if timeout_tx_flag = '1' then
write_ns <= tx_idle_st;
elsif ps2_clk_rx = '0' and ps2_data_rx = '0' then
write_ns <= tx_ack_sample_st;
end if;
when tx_ack_sample_st =>
if timeout_tx_flag = '1' then
write_ns <= tx_idle_st;
elsif ps2_clk_rx = '1' and ps2_data_rx = '1' then
write_ns <= tx_valid_st;
end if;
when others =>
write_ns <= tx_idle_st;
end case;
end process;
-------------------------------------------
end Behavioral;
+122
View File
@@ -0,0 +1,122 @@
--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 20:52:44 10/26/05
-- Design Name:
-- Module Name: ps2_phy - 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_phy is
Port
(
rst : in std_logic;
clk : in std_logic;
ps2_clk : inout std_logic;
ps2_data : inout std_logic;
rx_clk : out std_logic;
rx_data : out std_logic;
tx_clk : in std_logic;
tx_data : in std_logic
);
end ps2_phy;
architecture Behavioral of ps2_phy is
COMPONENT debounce
GENERIC (ncyc_latency : integer);
PORT
(
rst : IN std_logic;
clk : IN std_logic;
input : IN std_logic;
output : OUT std_logic
);
END COMPONENT;
signal clk_in : std_logic;
signal data_in : std_logic;
begin
Inst_debounce_clk: debounce
GENERIC MAP
(
ncyc_latency => 8
)
PORT MAP
(
rst => rst,
clk => clk,
input => clk_in,
output => rx_clk
);
Inst_debounce_data: debounce
GENERIC MAP
(
ncyc_latency => 8
)
PORT MAP
(
rst => rst,
clk => clk,
input => data_in,
output => rx_data
);
IOBUF_inst_ps2_clk : IOBUF
generic map
(
DRIVE => 2,
IBUF_DELAY_VALUE => "0", -- Specify the amount of added input delay for buffer, "0"-"16" (Spartan-3E only)
IFD_DELAY_VALUE => "AUTO", -- Specify the amount of added delay for input register, "AUTO", "0"-"8" (Spartan-3E only)
IOSTANDARD => "DEFAULT",
SLEW => "SLOW"
)
port map
(
O => clk_in, -- Buffer output
IO => ps2_clk, -- Buffer inout port (connect directly to top-level port)
I => tx_clk, -- Buffer input
T => tx_clk -- 3-state enable input
);
IOBUF_inst_ps2_data : IOBUF
generic map
(
DRIVE => 2,
IBUF_DELAY_VALUE => "0", -- Specify the amount of added input delay for buffer, "0"-"16" (Spartan-3E only)
IFD_DELAY_VALUE => "AUTO", -- Specify the amount of added delay for input register, "AUTO", "0"-"8" (Spartan-3E only)
IOSTANDARD => "DEFAULT",
SLEW => "SLOW"
)
port map
(
O => data_in, -- Buffer output
IO => ps2_data, -- Buffer inout port (connect directly to top-level port)
I => tx_data, -- Buffer input
T => tx_data -- 3-state enable input
);
end Behavioral;
+136
View File
@@ -0,0 +1,136 @@
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY ps2_wb IS
Generic
(
f_sys_clk_hz : integer := 100E6
);
Port
(
CLK_I : in STD_LOGIC;
RST_I : in STD_LOGIC;
CYC_I : in STD_LOGIC;
STB_I : in STD_LOGIC;
SEL_I : in unsigned(3 downto 0);
WE_I : in STD_LOGIC;
ACK_O : out STD_LOGIC;
SRDY_O : out STD_LOGIC;
MRDY_I : in STD_LOGIC;
ADDR_I : in unsigned(31 downto 0);
DAT_I : in unsigned(31 downto 0);
DAT_O : out unsigned(31 downto 0);
INT_O : out STD_LOGIC;
clk_rx : in std_logic;
data_rx : in std_logic;
clk_tx : out std_logic;
data_tx : out std_logic
);
END ps2_wb;
ARCHITECTURE behavior OF ps2_wb IS
-- Signals for ps2 connections
signal reg_we_ps2_tx : std_logic;
signal reg_re_ps2_rx : std_logic;
signal reg_ps2_tx : unsigned(7 downto 0);
signal reg_ps2_rx : unsigned(7 downto 0);
signal rx_data_present : std_logic;
signal ps2_status_port : unsigned(15 downto 0);
signal rx_int_en : std_logic;
signal tx_int_en : std_logic;
signal irq_rx : std_logic;
signal irq_tx : std_logic;
signal tx_empty : std_logic;
begin
SRDY_O <= CYC_I;
------------------------------------------------------------------
registers_write:
process(CLK_I)
begin
if rising_edge(CLK_I) then
reg_we_ps2_tx <= '0';
if RST_I = '1' then
rx_int_en <= '0';
tx_int_en <= '0';
elsif (STB_I and CYC_I and WE_I) = '1' then
case ADDR_I(5 downto 2) is
when "0000" =>
reg_we_ps2_tx <= '1';
reg_ps2_tx <= DAT_I(7 downto 0);
when "0001" =>
rx_int_en <= DAT_I(6);
tx_int_en <= DAT_I(5);
when others => null;
end case;
end if;
end if;
end process;
registers_read:
process(CLK_I)
begin
if rising_edge(CLK_I) then
reg_re_ps2_rx <= '0';
ACK_O <= '0';
if (STB_I and CYC_I) = '1' then
ACK_O <= not WE_I;
DAT_O <= (others => '0');
case ADDR_I(5 downto 2) is
when "0000" =>
reg_re_ps2_rx <= not WE_I;
DAT_O(7 downto 0) <= unsigned(reg_ps2_rx);
when "0001" =>
DAT_O(15 downto 0) <= ps2_status_port;
when others => null;
end case;
end if;
end if;
end process;
irq_register:
process(CLK_I)
begin
if rising_edge(CLK_I) then
INT_O <= irq_rx or irq_tx;
irq_tx <= tx_empty and tx_int_en;
irq_rx <= rx_data_present and rx_int_en;
end if;
end process;
inst_ps2_core: entity work.ps2_core
GENERIC MAP
(
f_sys_clk_hz => f_sys_clk_hz
)
PORT MAP
(
rst => RST_I,
clk => CLK_I,
din => reg_ps2_tx,
dout => reg_ps2_rx,
tx_empty => tx_empty,
rx_present => rx_data_present,
din_vld => reg_we_ps2_tx,
read_en => reg_re_ps2_rx,
ps2_clk_rx => clk_rx,
ps2_data_rx => data_rx,
ps2_clk_tx => clk_tx,
ps2_data_tx => data_tx
);
ps2_status_port <= "000000" & irq_rx & irq_tx & '0' & rx_int_en & tx_int_en & '0' & '0' & rx_data_present & '0' & tx_empty;
-- INT_O <= irq_rx or irq_tx;
end behavior;
+290
View File
@@ -0,0 +1,290 @@
--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 20:35:49 10/22/2005
-- Design Name: ps2_core
-- Module Name: tb_ps2_core.vhd
-- Project Name: ps2if
-- Target Device:
-- Tool versions:
-- Description:
--
-- VHDL Test Bench Created by ISE for module: ps2_core
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY tb_ps2_core IS
END tb_ps2_core;
ARCHITECTURE behavior OF tb_ps2_core IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT ps2_core
PORT(
rst : IN std_logic;
clk : IN std_logic;
din : IN unsigned(7 downto 0);
din_vld : IN std_logic;
read_en : IN std_logic;
ps2_clk_rx : IN std_logic;
ps2_data_rx : IN std_logic;
ps2_clk_tx : out std_logic;
ps2_data_tx : out std_logic;
dout : OUT unsigned(7 downto 0);
tx_empty : OUT std_logic;
rx_present : OUT std_logic
);
END COMPONENT;
--Constants
constant SYSPERIOD : time := 10 ns;
constant PS2PERIOD : time := 100 us;
--Inputs
SIGNAL rst : std_logic := '1';
SIGNAL clk : std_logic := '0';
SIGNAL din_vld : std_logic := '0';
SIGNAL read_en : std_logic := '0';
SIGNAL ps2_clk_rx : std_logic := '1';
SIGNAL ps2_data_rx : std_logic := '1';
SIGNAL din : unsigned(7 downto 0) := (others=>'0');
--Outputs
SIGNAL dout : unsigned(7 downto 0);
SIGNAL dout_reg : unsigned(7 downto 0);
SIGNAL tx_empty : std_logic;
SIGNAL rx_present : std_logic;
SIGNAL ps2_clk_i : std_logic := '1';
SIGNAL ps2_clk_j : std_logic := '1';
SIGNAL ps2_clk_tx : std_logic;
SIGNAL ps2_data_tx : std_logic;
SIGNAl tx_trig : std_logic := '0';
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: ps2_core
PORT MAP
(
rst => rst,
clk => clk,
din => din,
dout => dout,
tx_empty => tx_empty,
rx_present => rx_present,
din_vld => din_vld,
read_en => read_en,
ps2_clk_rx => ps2_clk_rx,
ps2_data_rx => ps2_data_rx,
ps2_clk_tx => ps2_clk_tx,
ps2_data_tx => ps2_data_tx
);
ps2_clk_j <= ps2_clk_i after PS2PERIOD/4;
tb_pswclk : PROCESS
BEGIN
wait until ps2_clk_j'event;
ps2_clk_rx <= ps2_clk_j;
-- wait for SYSPERIOD;
-- ps2_clk_rx <= not ps2_clk_j;
-- wait for SYSPERIOD;
-- ps2_clk_rx <= ps2_clk_j;
-- wait for SYSPERIOD;
-- ps2_clk_rx <= not ps2_clk_j;
-- wait for SYSPERIOD;
-- ps2_clk_rx <= ps2_clk_j;
-- wait for SYSPERIOD;
-- ps2_clk_rx <= not ps2_clk_j;
-- wait for SYSPERIOD;
-- ps2_clk_rx <= ps2_clk_j;
-- wait for SYSPERIOD;
-- ps2_clk_rx <= not ps2_clk_j;
-- wait for SYSPERIOD;
-- ps2_clk_rx <= ps2_clk_j;
END PROCESS;
tb_sysclk : PROCESS
BEGIN
clk <= not clk;
wait for SYSPERIOD/2;
END PROCESS;
read_en <= rx_present;
tb_read : PROCESS(clk)
BEGIN
if rising_edge(clk) then
if rx_present = '1' then
dout_reg <= dout;
end if;
end if;
END PROCESS;
tb_write : PROCESS
BEGIN
wait until ps2_clk_tx = '0';
wait for PS2PERIOD;
wait until ps2_data_tx = '0';
wait until ps2_clk_tx = '1';
wait for PS2PERIOD/2;
tx_trig <= '1';
END PROCESS;
tb : PROCESS
BEGIN
wait for 20*SYSPERIOD;
rst <= '0';
for iter in 1 to 2 loop
-- wait for 2*PS2PERIOD;
--Start bit
wait for PS2PERIOD/2;
ps2_clk_i <= '0';
ps2_data_rx <= '0';
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
--Data bit 0
wait for PS2PERIOD/2;
ps2_clk_i <= '0';
ps2_data_rx <= '1';
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
--Data bit 1
wait for PS2PERIOD/2;
ps2_clk_i <= '0';
ps2_data_rx <= '1';
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
--Data bit 2
wait for PS2PERIOD/2;
ps2_clk_i <= '0';
ps2_data_rx <= '0';
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
--Data bit 3
wait for PS2PERIOD/2;
ps2_clk_i <= '0';
ps2_data_rx <= '1';
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
--Data bit 4
wait for PS2PERIOD/2;
ps2_clk_i <= '0';
ps2_data_rx <= '1';
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
--Data bit 5
wait for PS2PERIOD/2;
ps2_clk_i <= '0';
ps2_data_rx <= '0';
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
--Data bit 6
wait for PS2PERIOD/2;
ps2_clk_i <= '0';
ps2_data_rx <= '1';
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
--Data bit 7
wait for PS2PERIOD/2;
ps2_clk_i <= '0';
ps2_data_rx <= '1';
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
--Parity
wait for PS2PERIOD/2;
ps2_clk_i <= '0';
ps2_data_rx <= '1';
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
--Stop
wait for PS2PERIOD/2;
ps2_clk_i <= '0';
ps2_data_rx <= '1';
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
end loop;
ps2_data_rx <= '1';
ps2_clk_i <= '1';
wait for PS2PERIOD;
wait until rising_edge(clk);
din <= x"A5";
din_vld <= '1';
wait until rising_edge(clk);
din_vld <= '0';
wait until tx_trig = '1';
wait for 2*PS2PERIOD;
-- Start
ps2_clk_i <= not ps2_clk_i;
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
wait for PS2PERIOD/2;
for iter in 1 to 8 loop
ps2_clk_i <= not ps2_clk_i;
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
wait for PS2PERIOD/2;
end loop;
-- Stop
ps2_clk_i <= not ps2_clk_i;
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
wait for PS2PERIOD/2;
-- Parity
ps2_clk_i <= not ps2_clk_i;
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
wait for PS2PERIOD/2;
ps2_data_rx <= '0';
ps2_clk_i <= not ps2_clk_i;
wait for PS2PERIOD/2;
ps2_clk_i <= not ps2_clk_i;
wait for PS2PERIOD/2;
ps2_data_rx <= '1';
ps2_clk_i <= '1';
-- Place stimulus here
wait; -- will wait forever
END PROCESS;
END;