OpenCores
URL https://opencores.org/ocsvn/gamepads/gamepads/trunk

Subversion Repositories gamepads

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 10 to Rev 11
    Reverse comparison

Rev 10 → Rev 11

/trunk/gcpad/bench/vhdl/tb-c.vhd
0,0 → 1,20
-------------------------------------------------------------------------------
--
-- Testbench for the
-- GCpad controller core
--
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
--
-- $Id: tb-c.vhd,v 1.1 2004-10-07 21:24:06 arniml Exp $
--
-------------------------------------------------------------------------------
 
configuration tb_behav_c0 of tb is
 
for behav
for basic_b : gcpad_basic
use configuration work.gcpad_basic_struct_c0;
end for;
end for;
 
end tb_behav_c0;
/trunk/gcpad/bench/vhdl/tb.vhd
0,0 → 1,352
-------------------------------------------------------------------------------
--
-- Testbench for the
-- GCpad controller core
--
-- $Id: tb.vhd,v 1.1 2004-10-07 21:24:06 arniml Exp $
--
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/gamepads/
--
-- The project homepage is located at:
-- http://www.opencores.org/projects.cgi/web/gamepads/overview
--
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
entity tb is
 
end tb;
 
 
use work.gcpad_pack.all;
 
architecture behav of tb is
 
constant period_c : time := 100 ns;
constant reset_level_c : natural := 0;
constant clocks_per_1us_c : natural := 10;
 
component gcpad_basic
generic (
reset_level_g : integer := 0;
clocks_per_1us_g : integer := 2
);
port (
clk_i : in std_logic;
reset_i : in std_logic;
pad_request_i : in std_logic;
pad_avail_o : out std_logic;
pad_data_io : inout std_logic;
but_a_o : out std_logic;
but_b_o : out std_logic;
but_x_o : out std_logic;
but_y_o : out std_logic;
but_z_o : out std_logic;
but_start_o : out std_logic;
but_tl_o : out std_logic;
but_tr_o : out std_logic;
but_left_o : out std_logic;
but_right_o : out std_logic;
but_up_o : out std_logic;
but_down_o : out std_logic;
ana_joy_x_o : out std_logic_vector(7 downto 0);
ana_joy_y_o : out std_logic_vector(7 downto 0);
ana_c_x_o : out std_logic_vector(7 downto 0);
ana_c_y_o : out std_logic_vector(7 downto 0);
ana_l_o : out std_logic_vector(7 downto 0);
ana_r_o : out std_logic_vector(7 downto 0)
);
end component;
 
signal clk_s : std_logic;
signal reset_s : std_logic;
 
signal pad_data_s : std_logic;
 
signal buttons_s : std_logic_vector(64 downto 0);
 
signal pad_request_s : std_logic;
signal pad_avail_s : std_logic;
 
begin
 
basic_b : gcpad_basic
generic map (
reset_level_g => reset_level_c,
clocks_per_1us_g => clocks_per_1us_c
)
port map (
clk_i => clk_s,
reset_i => reset_s,
pad_request_i => pad_request_s,
pad_avail_o => pad_avail_s,
pad_data_io => pad_data_s,
but_a_o => buttons_s(56),
but_b_o => buttons_s(57),
but_x_o => buttons_s(58),
but_y_o => buttons_s(59),
but_z_o => buttons_s(52),
but_start_o => buttons_s(60),
but_tl_o => buttons_s(54),
but_tr_o => buttons_s(53),
but_left_o => buttons_s(48),
but_right_o => buttons_s(49),
but_up_o => buttons_s(51),
but_down_o => buttons_s(50),
ana_joy_x_o => buttons_s(47 downto 40),
ana_joy_y_o => buttons_s(39 downto 32),
ana_c_x_o => buttons_s(31 downto 24),
ana_c_y_o => buttons_s(23 downto 16),
ana_l_o => buttons_s(15 downto 8),
ana_r_o => buttons_s( 7 downto 0)
);
 
buttons_s(64) <= '0';
buttons_s(63 downto 61) <= (others => '0');
buttons_s(55) <= '1';
 
 
-- pullup on pad_data
-- pad_data_s <= 'H';
 
 
stimuli: process
 
procedure check_request is
constant request_c : std_logic_vector(24 downto 0) := "H0H000000HH000000000000H0";
begin
 
-- read 25 bits from pad_data_s
for i in 0 to 24 loop
wait until pad_data_s = '0';
 
wait for 2 * clocks_per_1us_c * period_c;
if pad_data_s /= request_c(i) then
assert false
report "Found wrong level on pad_data_s while checking request packet!"
severity error;
end if;
 
wait for 2 * clocks_per_1us_c * period_c;
 
end loop;
 
 
end check_request;
 
procedure send_packet(packet : in std_logic_vector(64 downto 0)) is
variable time_low_v, time_high_v : time;
begin
-- send request;
pad_request_s <= '1';
wait for 1 * period_c;
pad_request_s <= '0';
 
check_request;
 
wait for 10 * 40 * period_c;
 
for i in packet'high downto 0 loop
if packet(i) = '0' then
time_low_v := 3 us;
time_high_v := 1 us;
else
time_low_v := 1 us;
time_high_v := 3 us;
end if;
 
pad_data_s <= '0';
wait for time_low_v;
 
pad_data_s <= 'H';
wait for time_high_v;
 
end loop;
 
wait until pad_avail_s = '1';
wait for 10 * period_c;
 
-- check result
for i in 1 to packet'high loop
assert packet(i) = buttons_s(i-1)
report "Button mismatch!"
severity error;
end loop;
 
end send_packet;
 
 
procedure timeout_gcpad is
begin
-- send request;
pad_request_s <= '1';
wait for 1 * period_c;
pad_request_s <= '0';
 
check_request;
 
wait until pad_avail_s = '1';
wait for 10 * period_c;
 
end timeout_gcpad;
 
begin
pad_data_s <= 'H';
pad_request_s <= '0';
 
wait until reset_s = '1';
wait for period_c * 4;
 
timeout_gcpad;
send_packet(packet => "00000000100000000000000000000000000000000000000000000000000000001");
wait for clocks_per_1us_c * 100 * period_c;
send_packet(packet => "00011111111111111111111111111111111111111111111111111111111111111");
send_packet(packet => "00010000100000000000000000000000000000000000000000000000000000001");
send_packet(packet => "00001000100000000000000000000000000000000000000000000000000000001");
send_packet(packet => "00000100100000000000000000000000000000000000000000000000000000001");
send_packet(packet => "00000010100000000000000000000000000000000000000000000000000000001");
send_packet(packet => "00000001100000000000000000000000000000000000000000000000000000001");
send_packet(packet => "00001010101010101010101010101010101010101010101010101010101010101");
send_packet(packet => "00010101110101010101010101010101010101010101010101010101010101011");
send_packet(packet => "00000000100000000000000000000000000000000000000000000000000000001");
send_packet(packet => "00000000110000000000000000000000000000000000000000000000000000001");
send_packet(packet => "00000000101000000000000000000000000000000000000000000000000000001");
send_packet(packet => "00000000100100000000000000000000000000000000000000000000000000001");
send_packet(packet => "00000000100010000000000000000000000000000000000000000000000000001");
send_packet(packet => "00000000100001000000000000000000000000000000000000000000000000001");
send_packet(packet => "00000000100000100000000000000000000000000000000000000000000000001");
send_packet(packet => "00000000100000010000000000000000000000000000000000000000000000001");
send_packet(packet => "00000000100000001000000000000000000000000000000000000000000000001");
send_packet(packet => "00000000100000000100000000000000000000000000000000000000000000001");
send_packet(packet => "00000000100000000010000000000000000000000000000000000000000000001");
send_packet(packet => "00000000100000000001000000000000000000000000000000000000000000001");
send_packet(packet => "00000000100000000000100000000000000000000000000000000000000000001");
send_packet(packet => "00000000100000000000010000000000000000000000000000000000000000001");
send_packet(packet => "00000000100000000000001000000000000000000000000000000000000000001");
send_packet(packet => "00000000100000000000000100000000000000000000000000000000000000001");
send_packet(packet => "00000000100000000000000010000000000000000000000000000000000000001");
send_packet(packet => "00000000100000000000000001000000000000000000000000000000000000001");
send_packet(packet => "00000000100000000000000000100000000000000000000000000000000000001");
send_packet(packet => "00000000100000000000000000010000000000000000000000000000000000001");
send_packet(packet => "00000000100000000000000000001000000000000000000000000000000000001");
send_packet(packet => "00000000100000000000000000000100000000000000000000000000000000001");
send_packet(packet => "00000000100000000000000000000010000000000000000000000000000000001");
send_packet(packet => "00000000100000000000000000000001000000000000000000000000000000001");
send_packet(packet => "00000000100000000000000000000000100000000000000000000000000000001");
send_packet(packet => "00000000100000000000000000000000010000000000000000000000000000001");
send_packet(packet => "00000000100000000000000000000000001000000000000000000000000000001");
send_packet(packet => "00000000100000000000000000000000000100000000000000000000000000001");
send_packet(packet => "00000000100000000000000000000000000010000000000000000000000000001");
send_packet(packet => "00000000100000000000000000000000000001000000000000000000000000001");
send_packet(packet => "00000000100000000000000000000000000000100000000000000000000000001");
send_packet(packet => "00000000100000000000000000000000000000010000000000000000000000001");
send_packet(packet => "00000000100000000000000000000000000000001000000000000000000000001");
send_packet(packet => "00000000100000000000000000000000000000000100000000000000000000001");
send_packet(packet => "00000000100000000000000000000000000000000010000000000000000000001");
send_packet(packet => "00000000100000000000000000000000000000000001000000000000000000001");
send_packet(packet => "00000000100000000000000000000000000000000000100000000000000000001");
send_packet(packet => "00000000100000000000000000000000000000000000010000000000000000001");
send_packet(packet => "00000000100000000000000000000000000000000000001000000000000000001");
send_packet(packet => "00000000100000000000000000000000000000000000000100000000000000001");
send_packet(packet => "00000000100000000000000000000000000000000000000010000000000000001");
send_packet(packet => "00000000100000000000000000000000000000000000000001000000000000001");
send_packet(packet => "00000000100000000000000000000000000000000000000000100000000000001");
send_packet(packet => "00000000100000000000000000000000000000000000000000010000000000001");
send_packet(packet => "00000000100000000000000000000000000000000000000000001000000000001");
send_packet(packet => "00000000100000000000000000000000000000000000000000000100000000001");
send_packet(packet => "00000000100000000000000000000000000000000000000000000010000000001");
send_packet(packet => "00000000100000000000000000000000000000000000000000000001000000001");
send_packet(packet => "00000000100000000000000000000000000000000000000000000000100000001");
send_packet(packet => "00000000100000000000000000000000000000000000000000000000010000001");
send_packet(packet => "00000000100000000000000000000000000000000000000000000000001000001");
send_packet(packet => "00000000100000000000000000000000000000000000000000000000000100001");
send_packet(packet => "00000000100000000000000000000000000000000000000000000000000010001");
send_packet(packet => "00000000100000000000000000000000000000000000000000000000000001001");
send_packet(packet => "00000000100000000000000000000000000000000000000000000000000000101");
send_packet(packet => "00000000100000000000000000000000000000000000000000000000000000011");
 
 
wait for period_c * 2*40;
assert false
report "End of simulation reached."
severity failure;
 
end process stimuli;
 
 
 
-----------------------------------------------------------------------------
-- Clock Generator
-----------------------------------------------------------------------------
clk: process
begin
clk_s <= '0';
wait for period_c / 2;
clk_s <= '1';
wait for period_c / 2;
end process clk;
 
 
-----------------------------------------------------------------------------
-- Reset Generator
-----------------------------------------------------------------------------
reset: process
begin
if reset_level_c = 0 then
reset_s <= '0';
else
reset_s <= '1';
end if;
 
wait for period_c * 4 + 10 ns;
 
reset_s <= not reset_s;
 
wait;
end process reset;
 
end behav;
 
 
-------------------------------------------------------------------------------
-- File History:
--
-- $Log: not supported by cvs2svn $
-------------------------------------------------------------------------------
/trunk/gcpad/rtl/vhdl/gcpad_basic-c.vhd
0,0 → 1,27
-------------------------------------------------------------------------------
--
-- GCpad controller core
--
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
--
-- $Id: gcpad_basic-c.vhd,v 1.1 2004-10-07 21:23:10 arniml Exp $
--
-------------------------------------------------------------------------------
 
configuration gcpad_basic_struct_c0 of gcpad_basic is
 
for struct
for ctrl_b : gcpad_ctrl
use configuration work.gcpad_ctrl_rtl_c0;
end for;
 
for tx_b : gcpad_tx
use configuration work.gcpad_tx_rtl_c0;
end for;
 
for rx_b : gcpad_rx
use configuration work.gcpad_rx_rtl_c0;
end for;
end for;
 
end gcpad_basic_struct_c0;
/trunk/gcpad/rtl/vhdl/gcpad_basic.vhd
0,0 → 1,264
-------------------------------------------------------------------------------
--
-- GCpad controller core
--
-- $Id: gcpad_basic.vhd,v 1.1 2004-10-07 21:23:10 arniml Exp $
--
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/gamepads/
--
-- The project homepage is located at:
-- http://www.opencores.org/projects.cgi/web/gamepads/overview
--
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
entity gcpad_basic is
 
generic (
reset_level_g : integer := 0;
clocks_per_1us_g : integer := 2
);
port (
-- System Interface -------------------------------------------------------
clk_i : in std_logic;
reset_i : in std_logic;
pad_request_i : in std_logic;
pad_avail_o : out std_logic;
-- Gamepad Interface ------------------------------------------------------
pad_data_io : inout std_logic;
-- Buttons Interface ------------------------------------------------------
but_a_o : out std_logic;
but_b_o : out std_logic;
but_x_o : out std_logic;
but_y_o : out std_logic;
but_z_o : out std_logic;
but_start_o : out std_logic;
but_tl_o : out std_logic;
but_tr_o : out std_logic;
but_left_o : out std_logic;
but_right_o : out std_logic;
but_up_o : out std_logic;
but_down_o : out std_logic;
ana_joy_x_o : out std_logic_vector(7 downto 0);
ana_joy_y_o : out std_logic_vector(7 downto 0);
ana_c_x_o : out std_logic_vector(7 downto 0);
ana_c_y_o : out std_logic_vector(7 downto 0);
ana_l_o : out std_logic_vector(7 downto 0);
ana_r_o : out std_logic_vector(7 downto 0)
);
 
end gcpad_basic;
 
 
use work.gcpad_pack.analog_axis_t;
 
architecture struct of gcpad_basic is
 
component gcpad_ctrl
generic (
reset_level_g : integer := 0
);
port (
clk_i : in std_logic;
reset_i : in std_logic;
pad_request_i : in std_logic;
pad_avail_o : out std_logic;
tx_start_o : out boolean;
tx_finished_i : in boolean;
rx_en_o : out boolean;
rx_done_i : in boolean
);
end component;
 
component gcpad_tx
generic (
reset_level_g : natural := 0;
clocks_per_1us_g : natural := 2
);
port (
clk_i : in std_logic;
reset_i : in std_logic;
pad_data_o : out std_logic;
tx_start_i : in boolean;
tx_finished_o : out boolean;
tx_size_i : in std_logic_vector( 4 downto 0);
tx_command_i : in std_logic_vector(23 downto 0)
);
end component;
 
component gcpad_rx
generic (
reset_level_g : integer := 0;
clocks_per_1us_g : integer := 2
);
port (
clk_i : in std_logic;
reset_i : in std_logic;
rx_en_i : in boolean;
rx_done_o : out boolean;
rx_size_i : in std_logic_vector(6 downto 0);
pad_data_i : in std_logic;
but_a_o : out std_logic;
but_b_o : out std_logic;
but_x_o : out std_logic;
but_y_o : out std_logic;
but_z_o : out std_logic;
but_start_o : out std_logic;
but_tl_o : out std_logic;
but_tr_o : out std_logic;
but_left_o : out std_logic;
but_right_o : out std_logic;
but_up_o : out std_logic;
but_down_o : out std_logic;
ana_joy_x_o : out analog_axis_t;
ana_joy_y_o : out analog_axis_t;
ana_c_x_o : out analog_axis_t;
ana_c_y_o : out analog_axis_t;
ana_l_o : out analog_axis_t;
ana_r_o : out analog_axis_t
);
end component;
 
 
-----------------------------------------------------------------------------
-- constants for standard status polling
constant rx_size_c : std_logic_vector( 6 downto 0) := "1000000";
signal rx_size_s : std_logic_vector( 6 downto 0);
--
constant tx_size_c : std_logic_vector( 4 downto 0) := "11000";
signal tx_size_s : std_logic_vector( 4 downto 0);
--
constant tx_command_c : std_logic_vector(23 downto 0) := "010000000000001100000010";
signal tx_command_s : std_logic_vector(23 downto 0);
--
-----------------------------------------------------------------------------
 
signal pad_data_tx_s : std_logic;
 
signal tx_start_s : boolean;
signal tx_finished_s : boolean;
 
signal rx_en_s,
rx_done_s : boolean;
 
begin
 
rx_size_s <= rx_size_c;
tx_size_s <= tx_size_c;
tx_command_s <= tx_command_c;
 
ctrl_b : gcpad_ctrl
generic map (
reset_level_g => reset_level_g
)
port map (
clk_i => clk_i,
reset_i => reset_i,
pad_request_i => pad_request_i,
pad_avail_o => pad_avail_o,
tx_start_o => tx_start_s,
tx_finished_i => tx_finished_s,
rx_en_o => rx_en_s,
rx_done_i => rx_done_s
);
 
tx_b : gcpad_tx
generic map (
reset_level_g => reset_level_g,
clocks_per_1us_g => clocks_per_1us_g
)
port map (
clk_i => clk_i,
reset_i => reset_i,
pad_data_o => pad_data_tx_s,
tx_start_i => tx_start_s,
tx_finished_o => tx_finished_s,
tx_size_i => tx_size_s,
tx_command_i => tx_command_s
);
 
rx_b : gcpad_rx
generic map (
reset_level_g => reset_level_g,
clocks_per_1us_g => clocks_per_1us_g
)
port map (
clk_i => clk_i,
reset_i => reset_i,
rx_en_i => rx_en_s,
rx_done_o => rx_done_s,
rx_size_i => rx_size_s,
pad_data_i => pad_data_io,
but_a_o => but_a_o,
but_b_o => but_b_o,
but_x_o => but_x_o,
but_y_o => but_y_o,
but_z_o => but_z_o,
but_start_o => but_start_o,
but_tl_o => but_tl_o,
but_tr_o => but_tr_o,
but_left_o => but_left_o,
but_right_o => but_right_o,
but_up_o => but_up_o,
but_down_o => but_down_o,
ana_joy_x_o => ana_joy_x_o,
ana_joy_y_o => ana_joy_y_o,
ana_c_x_o => ana_c_x_o,
ana_c_y_o => ana_c_y_o,
ana_l_o => ana_l_o,
ana_r_o => ana_r_o
);
 
 
-----------------------------------------------------------------------------
-- Open collector driver to pad data
-----------------------------------------------------------------------------
pad_data_io <= '0'
when pad_data_tx_s = '0' else
'Z';
 
end struct;
 
 
-------------------------------------------------------------------------------
-- File History:
--
-- $Log: not supported by cvs2svn $
-------------------------------------------------------------------------------
/trunk/gcpad/rtl/vhdl/gcpad_ctrl-c.vhd
0,0 → 1,16
-------------------------------------------------------------------------------
--
-- GCpad controller core
--
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
--
-- $Id: gcpad_ctrl-c.vhd,v 1.1 2004-10-07 21:23:10 arniml Exp $
--
-------------------------------------------------------------------------------
 
configuration gcpad_ctrl_rtl_c0 of gcpad_ctrl is
 
for rtl
end for;
 
end gcpad_ctrl_rtl_c0;
/trunk/gcpad/rtl/vhdl/gcpad_ctrl.vhd
0,0 → 1,209
-------------------------------------------------------------------------------
--
-- GCpad controller core
--
-- $Id: gcpad_ctrl.vhd,v 1.1 2004-10-07 21:23:10 arniml Exp $
--
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/gamepads/
--
-- The project homepage is located at:
-- http://www.opencores.org/projects.cgi/web/gamepads/overview
--
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
entity gcpad_ctrl is
 
generic (
reset_level_g : integer := 0
);
port (
-- System Interface -------------------------------------------------------
clk_i : in std_logic;
reset_i : in std_logic;
pad_request_i : in std_logic;
pad_avail_o : out std_logic;
-- Control Interface ------------------------------------------------------
tx_start_o : out boolean;
tx_finished_i : in boolean;
rx_en_o : out boolean;
rx_done_i : in boolean
);
 
end gcpad_ctrl;
 
 
use work.gcpad_pack.all;
 
architecture rtl of gcpad_ctrl is
 
type state_t is (IDLE,
TX,
RX_START,
RX_WAIT,
DEL1,
DEL1_WAIT,
DEL2,
DEL2_WAIT,
DEL3,
DEL3_WAIT);
signal state_s,
state_q : state_t;
 
begin
 
-----------------------------------------------------------------------------
-- Process seq
--
-- Purpose:
-- Implements the sequential elements.
--
seq: process (reset_i, clk_i)
begin
if reset_i = reset_level_g then
state_q <= IDLE;
 
elsif clk_i'event and clk_i = '1' then
state_q <= state_s;
 
end if;
 
end process seq;
--
-----------------------------------------------------------------------------
 
 
-----------------------------------------------------------------------------
-- Process fsm
--
-- Purpose:
-- Models the controlling state machine.
--
fsm: process (state_q,
tx_finished_i,
rx_done_i,
pad_request_i)
begin
rx_en_o <= false;
state_s <= IDLE;
tx_start_o <= false;
pad_avail_o <= '0';
 
case state_q is
when IDLE =>
if pad_request_i = '1' then
state_s <= TX;
tx_start_o <= true;
else
state_s <= IDLE;
end if;
 
when TX =>
if not tx_finished_i then
state_s <= TX;
else
state_s <= RX_START;
end if;
 
when RX_START =>
rx_en_o <= true;
state_s <= RX_WAIT;
 
when RX_WAIT =>
if rx_done_i then
state_s <= DEL1;
else
state_s <= RX_WAIT;
end if;
 
when DEL1 =>
-- start receiver and wait for its initial timeout
rx_en_o <= true;
state_s <= DEL1_WAIT;
 
when DEL1_WAIT =>
if rx_done_i then
state_s <= DEL2;
else
state_s <= DEL1_WAIT;
end if;
 
when DEL2 =>
-- start receiver and wait for its initial timeout
rx_en_o <= true;
state_s <= DEL2_WAIT;
 
when DEL2_WAIT =>
if rx_done_i then
state_s <= DEL3;
else
state_s <= DEL2_WAIT;
end if;
 
when DEL3 =>
-- start receiver and wait for its initial timeout
rx_en_o <= true;
state_s <= DEL3_WAIT;
 
when DEL3_WAIT =>
if rx_done_i then
pad_avail_o <= '1';
state_s <= IDLE;
else
state_s <= DEL3_WAIT;
end if;
 
when others =>
null;
 
end case;
 
end process fsm;
--
-----------------------------------------------------------------------------
 
end rtl;
 
 
-------------------------------------------------------------------------------
-- File History:
--
-- $Log: not supported by cvs2svn $
-------------------------------------------------------------------------------
/trunk/gcpad/rtl/vhdl/gcpad_rx-c.vhd
0,0 → 1,16
-------------------------------------------------------------------------------
--
-- GCpad controller core
--
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
--
-- $Id: gcpad_rx-c.vhd,v 1.1 2004-10-07 21:23:10 arniml Exp $
--
-------------------------------------------------------------------------------
 
configuration gcpad_rx_rtl_c0 of gcpad_rx is
 
for rtl
end for;
 
end gcpad_rx_rtl_c0;
/trunk/gcpad/rtl/vhdl/gcpad_rx.vhd
0,0 → 1,435
-------------------------------------------------------------------------------
--
-- GCpad controller core
--
-- $Id: gcpad_rx.vhd,v 1.1 2004-10-07 21:23:10 arniml Exp $
--
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/gamepads/
--
-- The project homepage is located at:
-- http://www.opencores.org/projects.cgi/web/gamepads/overview
--
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use work.gcpad_pack.analog_axis_t;
 
entity gcpad_rx is
 
generic (
reset_level_g : integer := 0;
clocks_per_1us_g : integer := 2
);
port (
-- System Interface -------------------------------------------------------
clk_i : in std_logic;
reset_i : in std_logic;
-- Control Interface ------------------------------------------------------
rx_en_i : in boolean;
rx_done_o : out boolean;
rx_size_i : in std_logic_vector(6 downto 0);
-- Gamepad Interface ------------------------------------------------------
pad_data_i : in std_logic;
-- Buttons Interface ------------------------------------------------------
but_a_o : out std_logic;
but_b_o : out std_logic;
but_x_o : out std_logic;
but_y_o : out std_logic;
but_z_o : out std_logic;
but_start_o : out std_logic;
but_tl_o : out std_logic;
but_tr_o : out std_logic;
but_left_o : out std_logic;
but_right_o : out std_logic;
but_up_o : out std_logic;
but_down_o : out std_logic;
ana_joy_x_o : out analog_axis_t;
ana_joy_y_o : out analog_axis_t;
ana_c_x_o : out analog_axis_t;
ana_c_y_o : out analog_axis_t;
ana_l_o : out analog_axis_t;
ana_r_o : out analog_axis_t
);
 
end gcpad_rx;
 
 
library ieee;
use ieee.numeric_std.all;
use work.gcpad_pack.all;
 
architecture rtl of gcpad_rx is
 
type state_t is (IDLE,
DETECT_TIMEOUT,
WAIT_FOR_1,
WAIT_FOR_0,
FINISHED);
signal state_s,
state_q : state_t;
 
signal buttons_q,
shift_buttons_q : buttons_t;
signal save_buttons_s : boolean;
signal shift_buttons_s : boolean;
 
constant cnt_sample_high_c : natural := clocks_per_1us_g * 4 - 1;
subtype cnt_sample_t is natural range 0 to cnt_sample_high_c;
signal cnt_zeros_q : cnt_sample_t;
signal cnt_ones_q : cnt_sample_t;
signal sampled_s : boolean;
signal sync_sample_s : boolean;
signal wrap_sample_s : boolean;
signal sample_underflow_q : boolean;
 
signal more_ones_q : boolean;
 
-- timeout counter counts three sample undeflows
constant cnt_timeout_high_c : natural := 3;
subtype cnt_timeout_t is natural range 0 to cnt_timeout_high_c;
signal cnt_timeout_q : cnt_timeout_t;
signal timeout_q : boolean;
signal sync_timeout_s : boolean;
 
 
subtype num_buttons_read_t is unsigned(6 downto 0);
signal num_buttons_read_q : num_buttons_read_t;
signal all_buttons_read_s : boolean;
signal reset_num_buttons_s : boolean;
 
signal pad_data_sync_q : std_logic_vector(1 downto 0);
signal pad_data_s : std_logic;
 
signal rx_done_q,
set_rx_done_s : boolean;
 
begin
 
-----------------------------------------------------------------------------
-- Process seq
--
-- Purpose:
-- Implements the sequential elements of this module.
--
seq: process (reset_i, clk_i)
variable dec_timeout_v : boolean;
begin
if reset_i = reset_level_g then
buttons_q <= (others => '0');
shift_buttons_q <= (others => '0');
 
state_q <= IDLE;
 
cnt_zeros_q <= cnt_sample_high_c;
cnt_ones_q <= cnt_sample_high_c;
more_ones_q <= false;
sample_underflow_q <= false;
 
cnt_timeout_q <= cnt_timeout_high_c;
 
timeout_q <= false;
 
num_buttons_read_q <= (others => '0');
rx_done_q <= false;
 
pad_data_sync_q <= (others => '1');
 
 
elsif clk_i'event and clk_i = '1' then
-- synchronizer for pad data
pad_data_sync_q(0) <= pad_data_i;
pad_data_sync_q(1) <= pad_data_sync_q(0);
 
 
state_q <= state_s;
 
 
dec_timeout_v := false;
-- sample counter
if sync_sample_s then
-- explicit preload
cnt_zeros_q <= cnt_sample_high_c;
cnt_ones_q <= cnt_sample_high_c;
else
if cnt_zeros_q = 0 then
if wrap_sample_s then
cnt_zeros_q <= cnt_sample_high_c;
end if;
dec_timeout_v := true;
elsif pad_data_s = '0' then
cnt_zeros_q <= cnt_zeros_q - 1;
end if;
 
if cnt_ones_q = 0 then
if wrap_sample_s then
cnt_ones_q <= cnt_sample_high_c;
end if;
dec_timeout_v := true;
elsif pad_data_s /= '0' then
cnt_ones_q <= cnt_ones_q - 1;
end if;
end if;
 
if cnt_ones_q < cnt_zeros_q then
more_ones_q <= true;
else
more_ones_q <= false;
end if;
 
-- detect sample underflow
sample_underflow_q <= dec_timeout_v;
 
-- timeout counter
if sync_timeout_s then
-- explicit preload
cnt_timeout_q <= cnt_timeout_high_c;
timeout_q <= false;
elsif cnt_timeout_q = 0 then
-- wrap-around
cnt_timeout_q <= cnt_timeout_high_c;
timeout_q <= true;
elsif dec_timeout_v then
-- decrement counter when sampler wraps around
cnt_timeout_q <= cnt_timeout_q - 1;
end if;
 
 
-- count remaining number of buttons to read
if shift_buttons_s then
shift_buttons_q(buttons_t'high downto 1) <= shift_buttons_q(buttons_t'high-1 downto 0);
 
if more_ones_q then
shift_buttons_q(0) <= '1';
else
shift_buttons_q(0) <= '0';
end if;
 
end if;
 
if reset_num_buttons_s then
-- explicit preload
num_buttons_read_q <= unsigned(rx_size_i);
elsif shift_buttons_s then
-- decrement counter when a button bit has been read
if not all_buttons_read_s then
num_buttons_read_q <= num_buttons_read_q - 1;
end if;
end if;
 
 
-- the buttons
if save_buttons_s then
buttons_q <= shift_buttons_q;
end if;
 
if set_rx_done_s then
rx_done_q <= true;
else
rx_done_q <= false;
end if;
 
end if;
 
end process seq;
--
-----------------------------------------------------------------------------
 
pad_data_s <= pad_data_sync_q(1);
 
-- indicates that all buttons have been read
all_buttons_read_s <= num_buttons_read_q = 0;
 
 
-----------------------------------------------------------------------------
-- Process fsm
--
-- Purpose:
-- Models the controlling state machine.
--
fsm: process (state_q,
rx_en_i,
pad_data_s,
all_buttons_read_s,
sampled_s,
sample_underflow_q,
timeout_q)
begin
sync_sample_s <= false;
sync_timeout_s <= false;
state_s <= IDLE;
shift_buttons_s <= false;
save_buttons_s <= false;
set_rx_done_s <= false;
reset_num_buttons_s <= false;
wrap_sample_s <= false;
 
case state_q is
-- IDLE -----------------------------------------------------------------
-- The idle state.
when IDLE =>
if rx_en_i then
state_s <= DETECT_TIMEOUT;
 
else
-- keep counters synchronized when no reception is running
sync_sample_s <= true;
sync_timeout_s <= true;
reset_num_buttons_s <= true;
state_s <= IDLE;
 
end if;
 
when DETECT_TIMEOUT =>
state_s <= DETECT_TIMEOUT;
 
if pad_data_s = '0' then
sync_sample_s <= true;
state_s <= WAIT_FOR_1;
 
else
-- wait for timeout
wrap_sample_s <= true;
if timeout_q then
set_rx_done_s <= true;
state_s <= IDLE;
end if;
 
end if;
 
 
-- WAIT_FOR_1 -----------------------------------------------------------
-- Sample counter has expired and a 0 bit has been detected.
-- We must now wait for pad_data_s to become 1.
-- Or abort upon timeout.
when WAIT_FOR_1 =>
if pad_data_s = '0' then
if not sample_underflow_q then
state_s <= WAIT_FOR_1;
else
-- timeout while reading buttons!
set_rx_done_s <= true;
state_s <= IDLE;
end if;
 
else
state_s <= WAIT_FOR_0;
end if;
 
-- WAIT_FOR_0 -----------------------------------------------------------
-- pad_data_s is at 1 level now and no timeout occured so far.
-- We wait for the next 0 level on pad_data_s or abort upon timeout.
when WAIT_FOR_0 =>
-- wait for falling edge of pad data
if pad_data_s = '0' then
sync_sample_s <= true;
 
if not all_buttons_read_s then
-- loop another time if there are still some buttons to read
shift_buttons_s <= true;
state_s <= WAIT_FOR_1;
else
state_s <= WAIT_FOR_0;
end if;
 
else
if sample_underflow_q then
if all_buttons_read_s then
-- last button was read
-- so it's ok to timeout
state_s <= FINISHED;
else
-- timeout while reading buttons!
set_rx_done_s <= true;
state_s <= IDLE;
end if;
 
else
state_s <= WAIT_FOR_0;
 
end if;
 
end if;
 
when FINISHED =>
-- finally save buttons
save_buttons_s <= true;
set_rx_done_s <= true;
 
when others =>
null;
 
end case;
 
end process fsm;
--
-----------------------------------------------------------------------------
 
 
-----------------------------------------------------------------------------
-- Output Mapping
-----------------------------------------------------------------------------
rx_done_o <= rx_done_q;
but_a_o <= buttons_q(pos_a_c);
but_b_o <= buttons_q(pos_b_c);
but_x_o <= buttons_q(pos_x_c);
but_y_o <= buttons_q(pos_y_c);
but_z_o <= buttons_q(pos_z_c);
but_start_o <= buttons_q(pos_start_c);
but_tl_o <= buttons_q(pos_tl_c);
but_tr_o <= buttons_q(pos_tr_c);
but_left_o <= buttons_q(pos_left_c);
but_right_o <= buttons_q(pos_right_c);
but_up_o <= buttons_q(pos_up_c);
but_down_o <= buttons_q(pos_down_c);
ana_joy_x_o <= buttons_q(joy_x_high_c downto joy_x_low_c);
ana_joy_y_o <= buttons_q(joy_y_high_c downto joy_y_low_c);
ana_c_x_o <= buttons_q(c_x_high_c downto c_x_low_c);
ana_c_y_o <= buttons_q(c_y_high_c downto c_y_low_c);
ana_l_o <= buttons_q(l_high_c downto l_low_c);
ana_r_o <= buttons_q(r_high_c downto r_low_c);
 
 
end rtl;
 
 
-------------------------------------------------------------------------------
-- File History:
--
-- $Log: not supported by cvs2svn $
-------------------------------------------------------------------------------
/trunk/gcpad/rtl/vhdl/gcpad_pack-p.vhd
0,0 → 1,98
-------------------------------------------------------------------------------
--
-- GCpad controller core
--
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
--
-- $Id: gcpad_pack-p.vhd,v 1.1 2004-10-07 21:23:10 arniml Exp $
--
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
package gcpad_pack is
 
subtype analog_axis_t is std_logic_vector(7 downto 0);
constant num_buttons_c : natural := 64;
subtype buttons_t is std_logic_vector(num_buttons_c-1 downto 0);
 
function "=" (a : in std_logic; b : in integer) return boolean;
 
-----------------------------------------------------------------------------
-- The button positions inside a gc packet
-----------------------------------------------------------------------------
-- byte 7 -------------------------------------------------------------------
constant pos_errstat_c : natural := 63;
constant pos_errlatch_c : natural := 62;
constant pos_unknown1_c : natural := 61;
constant pos_start_c : natural := 60;
constant pos_y_c : natural := 59;
constant pos_x_c : natural := 58;
constant pos_b_c : natural := 57;
constant pos_a_c : natural := 56;
-- byte 6 -------------------------------------------------------------------
constant pos_unknown2_c : natural := 55;
constant pos_tl_c : natural := 54;
constant pos_tr_c : natural := 53;
constant pos_z_c : natural := 52;
constant pos_up_c : natural := 51;
constant pos_down_c : natural := 50;
constant pos_right_c : natural := 49;
constant pos_left_c : natural := 48;
-- byte 5 -------------------------------------------------------------------
constant joy_x_high_c : natural := 47;
constant joy_x_low_c : natural := 40;
-- byte 4 -------------------------------------------------------------------
constant joy_y_high_c : natural := 39;
constant joy_y_low_c : natural := 32;
-- byte 3 -------------------------------------------------------------------
constant c_x_high_c : natural := 31;
constant c_x_low_c : natural := 24;
-- byte 2 -------------------------------------------------------------------
constant c_y_high_c : natural := 23;
constant c_y_low_c : natural := 16;
-- byte 1 -------------------------------------------------------------------
constant l_high_c : natural := 15;
constant l_low_c : natural := 8;
-- byte 0 -------------------------------------------------------------------
constant r_high_c : natural := 7;
constant r_low_c : natural := 0;
 
end gcpad_pack;
 
 
package body gcpad_pack is
 
-----------------------------------------------------------------------------
-- Function =
--
-- Compares a std_logic with an integer.
--
function "=" (a : in std_logic; b : in integer) return boolean is
variable result_v : boolean;
begin
result_v := false;
 
case a is
when '0' =>
if b = 0 then
result_v := true;
end if;
 
when '1' =>
if b = 1 then
result_v := true;
end if;
 
when others =>
null;
 
end case;
 
return result_v;
end;
--
-----------------------------------------------------------------------------
 
end gcpad_pack;
/trunk/gcpad/rtl/vhdl/gcpad_tx-c.vhd
0,0 → 1,16
-------------------------------------------------------------------------------
--
-- GCpad controller core
--
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
--
-- $Id: gcpad_tx-c.vhd,v 1.1 2004-10-07 21:23:10 arniml Exp $
--
-------------------------------------------------------------------------------
 
configuration gcpad_tx_rtl_c0 of gcpad_tx is
 
for rtl
end for;
 
end gcpad_tx_rtl_c0;
/trunk/gcpad/rtl/vhdl/gcpad_tx.vhd
0,0 → 1,304
-------------------------------------------------------------------------------
--
-- GCpad controller core
--
-- $Id: gcpad_tx.vhd,v 1.1 2004-10-07 21:23:10 arniml Exp $
--
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/gamepads/
--
-- The project homepage is located at:
-- http://www.opencores.org/projects.cgi/web/gamepads/overview
--
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
entity gcpad_tx is
 
generic (
reset_level_g : natural := 0;
clocks_per_1us_g : natural := 2
);
port (
-- System Interface -------------------------------------------------------
clk_i : in std_logic;
reset_i : in std_logic;
-- Pad Interface ----------------------------------------------------------
pad_data_o : out std_logic;
-- Control Interface ------------------------------------------------------
tx_start_i : in boolean;
tx_finished_o : out boolean;
tx_size_i : in std_logic_vector( 4 downto 0);
tx_command_i : in std_logic_vector(23 downto 0)
);
 
end gcpad_tx;
 
 
library ieee;
use ieee.numeric_std.all;
 
use work.gcpad_pack.all;
 
architecture rtl of gcpad_tx is
 
subtype command_t is std_logic_vector(24 downto 0);
 
signal command_q : command_t;
signal load_command_s : boolean;
signal shift_bits_s : boolean;
 
constant cnt_long_c : natural := clocks_per_1us_g * 4 - 1;
constant cnt_short_c : natural := clocks_per_1us_g * 1 - 1;
subtype cnt_t is natural range 0 to cnt_long_c;
signal cnt_q : cnt_t;
signal cnt_load_long_s : boolean;
signal cnt_load_short_s : boolean;
signal cnt_finished_s : boolean;
 
subtype num_bits_t is unsigned(4 downto 0);
signal num_bits_q : num_bits_t;
signal all_bits_sent_s : boolean;
signal cnt_bit_s : boolean;
 
type state_t is (IDLE,
LOAD_COMMAND,
SEND_COMMAND_PHASE1,
SEND_COMMAND_PHASE2);
signal state_s,
state_q : state_t;
 
signal pad_data_s,
pad_data_q : std_logic;
 
signal tx_finished_s,
tx_finished_q : boolean;
 
begin
 
-----------------------------------------------------------------------------
-- Process seq
--
-- Purpose:
-- Implements the sequential elements of this module.
--
seq: process (reset_i, clk_i)
begin
if reset_i = reset_level_g then
command_q <= (others => '1');
cnt_q <= cnt_long_c;
num_bits_q <= (others => '0');
pad_data_q <= '1';
state_q <= IDLE;
tx_finished_q <= false;
 
elsif clk_i'event and clk_i = '1' then
tx_finished_q <= tx_finished_s;
 
-- fsm
state_q <= state_s;
 
-- command register and bit counter
if load_command_s then
command_q(24 downto 1) <= tx_command_i;
command_q(0) <= '1';
num_bits_q <= unsigned(tx_size_i) + 1;
 
else
if shift_bits_s then
command_q(command_t'high downto 1) <= command_q(command_t'high-1 downto 0);
end if;
 
if cnt_bit_s and not all_bits_sent_s then
num_bits_q <= num_bits_q - 1;
end if;
 
end if;
 
 
-- PWM counter
if cnt_load_long_s then
cnt_q <= cnt_long_c;
elsif cnt_load_short_s then
cnt_q <= cnt_short_c;
else
if not cnt_finished_s then
cnt_q <= cnt_q - 1;
end if;
end if;
 
-- PWM output = pad data
pad_data_q <= pad_data_s;
 
end if;
 
end process seq;
--
-----------------------------------------------------------------------------
 
-- indicates that PWM counter has finished
cnt_finished_s <= cnt_q = 0;
-- indicates that all bits have been sent
all_bits_sent_s <= num_bits_q = 0;
 
 
-----------------------------------------------------------------------------
-- Process fsm
--
-- Purpose:
-- Models the controlling state machine.
--
fsm: process (state_q,
cnt_finished_s,
all_bits_sent_s,
tx_start_i,
command_q)
begin
-- defaul assignments
state_s <= IDLE;
shift_bits_s <= false;
cnt_load_long_s <= false;
cnt_load_short_s <= false;
pad_data_s <= '1';
tx_finished_s <= false;
load_command_s <= false;
cnt_bit_s <= false;
 
case state_q is
-- IDLE -----------------------------------------------------------------
-- The idle state.
-- Advances when the transmitter is started
when IDLE =>
if tx_start_i then
state_s <= LOAD_COMMAND;
else
state_s <= IDLE;
end if;
 
 
-- LOAD_COMMAND ---------------------------------------------------------
-- Prepares the first and all subsequent low phases on pad_data_s.
when LOAD_COMMAND =>
state_s <= SEND_COMMAND_PHASE2;
load_command_s <= true;
 
-- start counter once to kick the loop
cnt_load_short_s <= true;
 
 
-- SEND_COMMAND_PHASE1 --------------------------------------------------
-- Wait for completion of phase 1, the low phase of pad_data_s.
-- The high phase is prepared when the PWM counter has expired.
when SEND_COMMAND_PHASE1 =>
state_s <= SEND_COMMAND_PHASE1;
pad_data_s <= '0';
 
if cnt_finished_s then
-- initiate high phase
pad_data_s <= '1';
if command_q(command_t'high) = '1' then
cnt_load_long_s <= true;
else
cnt_load_short_s <= true;
end if;
 
state_s <= SEND_COMMAND_PHASE2;
-- provide next bit
shift_bits_s <= true;
 
end if;
 
-- SEND_COMMAND_PHASE2 --------------------------------------------------
-- Wait for completion of phase 2, the high phase of pad_data_s.
-- The next low phase is prepared when the PWM counter has expired.
-- In case all bits have been sent, the tx handshake is asserted and
-- the FSM returns to IDLE state.
when SEND_COMMAND_PHASE2 =>
pad_data_s <= '1';
state_s <= SEND_COMMAND_PHASE2;
 
if cnt_finished_s then
if not all_bits_sent_s then
-- more bits to send so loop
 
-- prepare low phase
if command_q(command_t'high) = '1' then
cnt_load_short_s <= true;
else
cnt_load_long_s <= true;
end if;
 
-- decrement bit counter
cnt_bit_s <= true;
 
state_s <= SEND_COMMAND_PHASE1;
 
else
-- all bits sent, we're finished
tx_finished_s <= true;
state_s <= IDLE;
 
end if;
 
end if;
 
when others =>
null;
 
end case;
 
end process fsm;
--
-----------------------------------------------------------------------------
 
 
-----------------------------------------------------------------------------
-- Output mapping
-----------------------------------------------------------------------------
tx_finished_o <= tx_finished_q;
pad_data_o <= pad_data_q;
 
end rtl;
 
 
-------------------------------------------------------------------------------
-- File History:
--
-- $Log: not supported by cvs2svn $
-------------------------------------------------------------------------------
/trunk/gcpad/sim/rtl_sim/Makefile
0,0 → 1,88
##############################################################################
#
# Tool-specific Makefile for the GHDL compiler.
#
# $Id: Makefile,v 1.1 2004-10-07 21:25:20 arniml Exp $
#
# Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
#
# All rights reserved
#
##############################################################################
 
 
PROJECT_DIR = ../..
RTL_DIR = $(PROJECT_DIR)/rtl/vhdl
BENCH_DIR = $(PROJECT_DIR)/bench/vhdl
 
 
 
ANALYZE=ghdl -a --std=87 --workdir=work
ELABORATE=ghdl -e --std=87 --workdir=work
 
.PHONY: all
all: work elaborate
 
work:
mkdir work
 
work/gcpad_pack-p.o: $(RTL_DIR)/gcpad_pack-p.vhd
$(ANALYZE) $(RTL_DIR)/gcpad_pack-p.vhd
 
work/gcpad_rx.o: $(RTL_DIR)/gcpad_rx.vhd \
work/gcpad_pack-p.o
$(ANALYZE) $(RTL_DIR)/gcpad_rx.vhd
work/gcpad_rx-c.o: $(RTL_DIR)/gcpad_rx-c.vhd \
work/gcpad_rx.o
$(ANALYZE) $(RTL_DIR)/gcpad_rx-c.vhd
 
work/gcpad_tx.o: $(RTL_DIR)/gcpad_tx.vhd \
work/gcpad_pack-p.o
$(ANALYZE) $(RTL_DIR)/gcpad_tx.vhd
work/gcpad_tx-c.o: $(RTL_DIR)/gcpad_tx-c.vhd \
work/gcpad_tx.o
$(ANALYZE) $(RTL_DIR)/gcpad_tx-c.vhd
 
work/gcpad_ctrl.o: $(RTL_DIR)/gcpad_ctrl.vhd \
work/gcpad_pack-p.o
$(ANALYZE) $(RTL_DIR)/gcpad_ctrl.vhd
work/gcpad_ctrl-c.o: $(RTL_DIR)/gcpad_ctrl-c.vhd \
work/gcpad_ctrl.o
$(ANALYZE) $(RTL_DIR)/gcpad_ctrl-c.vhd
 
work/gcpad_basic.o: $(RTL_DIR)/gcpad_basic.vhd \
work/gcpad_pack-p.o \
work/gcpad_ctrl.o \
work/gcpad_tx.o \
work/gcpad_rx.o
$(ANALYZE) $(RTL_DIR)/gcpad_basic.vhd
work/gcpad_basic-c.o: $(RTL_DIR)/gcpad_basic-c.vhd \
work/gcpad_basic.o \
work/gcpad_ctrl-c.o \
work/gcpad_tx-c.o \
work/gcpad_rx-c.o
$(ANALYZE) $(RTL_DIR)/gcpad_basic-c.vhd
 
work/tb.o: $(BENCH_DIR)/tb.vhd \
work/gcpad_pack-p.o \
work/gcpad_basic.o
$(ANALYZE) $(BENCH_DIR)/tb.vhd
work/tb-c.o: $(BENCH_DIR)/tb-c.vhd \
work/tb.o \
work/gcpad_basic-c.o
$(ANALYZE) $(BENCH_DIR)/tb-c.vhd
 
 
.PHONY: elaborate
elaborate: tb_behav_c0
 
tb_behav_c0: analyze
$(ELABORATE) tb_behav_c0; \
strip tb_behav_c0
 
.PHONY: analyze
analyze: work/tb-c.o
 
.PHONY: clean
clean:
rm -rf work tb_behav_c0 *~

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.