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 *~ |