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

Subversion Repositories gamepads

[/] [gamepads/] [trunk/] [gcpad/] [rtl/] [vhdl/] [gcpad_rx.vhd] - Blame information for rev 11

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 arniml
-------------------------------------------------------------------------------
2
--
3
-- GCpad controller core
4
--
5
-- $Id: gcpad_rx.vhd,v 1.1 2004-10-07 21:23:10 arniml Exp $
6
--
7
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
8
--
9
-- All rights reserved
10
--
11
-- Redistribution and use in source and synthezised forms, with or without
12
-- modification, are permitted provided that the following conditions are met:
13
--
14
-- Redistributions of source code must retain the above copyright notice,
15
-- this list of conditions and the following disclaimer.
16
--
17
-- Redistributions in synthesized form must reproduce the above copyright
18
-- notice, this list of conditions and the following disclaimer in the
19
-- documentation and/or other materials provided with the distribution.
20
--
21
-- Neither the name of the author nor the names of other contributors may
22
-- be used to endorse or promote products derived from this software without
23
-- specific prior written permission.
24
--
25
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
29
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35
-- POSSIBILITY OF SUCH DAMAGE.
36
--
37
-- Please report bugs to the author, but before you do so, please
38
-- make sure that this is not a derivative work and that
39
-- you have the latest version of this file.
40
--
41
-- The latest version of this file can be found at:
42
--      http://www.opencores.org/cvsweb.shtml/gamepads/
43
--
44
-- The project homepage is located at:
45
--      http://www.opencores.org/projects.cgi/web/gamepads/overview
46
--
47
-------------------------------------------------------------------------------
48
 
49
library ieee;
50
use ieee.std_logic_1164.all;
51
use work.gcpad_pack.analog_axis_t;
52
 
53
entity gcpad_rx is
54
 
55
  generic (
56
    reset_level_g    :     integer := 0;
57
    clocks_per_1us_g :     integer := 2
58
  );
59
  port (
60
    -- System Interface -------------------------------------------------------
61
    clk_i            : in  std_logic;
62
    reset_i          : in  std_logic;
63
    -- Control Interface ------------------------------------------------------
64
    rx_en_i          : in  boolean;
65
    rx_done_o        : out boolean;
66
    rx_size_i        : in  std_logic_vector(6 downto 0);
67
    -- Gamepad Interface ------------------------------------------------------
68
    pad_data_i       : in  std_logic;
69
    -- Buttons Interface ------------------------------------------------------
70
    but_a_o          : out std_logic;
71
    but_b_o          : out std_logic;
72
    but_x_o          : out std_logic;
73
    but_y_o          : out std_logic;
74
    but_z_o          : out std_logic;
75
    but_start_o      : out std_logic;
76
    but_tl_o         : out std_logic;
77
    but_tr_o         : out std_logic;
78
    but_left_o       : out std_logic;
79
    but_right_o      : out std_logic;
80
    but_up_o         : out std_logic;
81
    but_down_o       : out std_logic;
82
    ana_joy_x_o      : out analog_axis_t;
83
    ana_joy_y_o      : out analog_axis_t;
84
    ana_c_x_o        : out analog_axis_t;
85
    ana_c_y_o        : out analog_axis_t;
86
    ana_l_o          : out analog_axis_t;
87
    ana_r_o          : out analog_axis_t
88
  );
89
 
90
end gcpad_rx;
91
 
92
 
93
library ieee;
94
use ieee.numeric_std.all;
95
use work.gcpad_pack.all;
96
 
97
architecture rtl of gcpad_rx is
98
 
99
  type state_t is (IDLE,
100
                   DETECT_TIMEOUT,
101
                   WAIT_FOR_1,
102
                   WAIT_FOR_0,
103
                   FINISHED);
104
  signal state_s,
105
         state_q  : state_t;
106
 
107
  signal buttons_q,
108
         shift_buttons_q : buttons_t;
109
  signal save_buttons_s  : boolean;
110
  signal shift_buttons_s : boolean;
111
 
112
  constant cnt_sample_high_c  : natural := clocks_per_1us_g * 4 - 1;
113
  subtype  cnt_sample_t       is natural range 0 to cnt_sample_high_c;
114
  signal   cnt_zeros_q        : cnt_sample_t;
115
  signal   cnt_ones_q         : cnt_sample_t;
116
  signal   sampled_s          : boolean;
117
  signal   sync_sample_s      : boolean;
118
  signal   wrap_sample_s      : boolean;
119
  signal   sample_underflow_q : boolean;
120
 
121
  signal   more_ones_q    : boolean;
122
 
123
  -- timeout counter counts three sample undeflows
124
  constant cnt_timeout_high_c : natural := 3;
125
  subtype  cnt_timeout_t      is natural range 0 to cnt_timeout_high_c;
126
  signal   cnt_timeout_q      : cnt_timeout_t;
127
  signal   timeout_q          : boolean;
128
  signal   sync_timeout_s     : boolean;
129
 
130
 
131
  subtype num_buttons_read_t  is unsigned(6 downto 0);
132
  signal  num_buttons_read_q  : num_buttons_read_t;
133
  signal  all_buttons_read_s  : boolean;
134
  signal  reset_num_buttons_s : boolean;
135
 
136
  signal pad_data_sync_q : std_logic_vector(1 downto 0);
137
  signal pad_data_s      : std_logic;
138
 
139
  signal rx_done_q,
140
         set_rx_done_s : boolean;
141
 
142
begin
143
 
144
  -----------------------------------------------------------------------------
145
  -- Process seq
146
  --
147
  -- Purpose:
148
  --   Implements the sequential elements of this module.
149
  --
150
  seq: process (reset_i, clk_i)
151
    variable dec_timeout_v : boolean;
152
  begin
153
    if reset_i = reset_level_g then
154
      buttons_q       <= (others => '0');
155
      shift_buttons_q <= (others => '0');
156
 
157
      state_q              <= IDLE;
158
 
159
      cnt_zeros_q          <= cnt_sample_high_c;
160
      cnt_ones_q           <= cnt_sample_high_c;
161
      more_ones_q          <= false;
162
      sample_underflow_q   <= false;
163
 
164
      cnt_timeout_q        <= cnt_timeout_high_c;
165
 
166
      timeout_q            <= false;
167
 
168
      num_buttons_read_q   <= (others => '0');
169
      rx_done_q            <= false;
170
 
171
      pad_data_sync_q      <= (others => '1');
172
 
173
 
174
    elsif clk_i'event and clk_i = '1' then
175
      -- synchronizer for pad data
176
      pad_data_sync_q(0) <= pad_data_i;
177
      pad_data_sync_q(1) <= pad_data_sync_q(0);
178
 
179
 
180
      state_q <= state_s;
181
 
182
 
183
      dec_timeout_v := false;
184
      -- sample counter
185
      if sync_sample_s then
186
        -- explicit preload
187
        cnt_zeros_q <= cnt_sample_high_c;
188
        cnt_ones_q  <= cnt_sample_high_c;
189
      else
190
        if cnt_zeros_q = 0 then
191
          if wrap_sample_s then
192
            cnt_zeros_q   <= cnt_sample_high_c;
193
          end if;
194
          dec_timeout_v := true;
195
        elsif pad_data_s = '0' then
196
          cnt_zeros_q   <= cnt_zeros_q - 1;
197
        end if;
198
 
199
        if cnt_ones_q = 0 then
200
          if wrap_sample_s then
201
            cnt_ones_q    <= cnt_sample_high_c;
202
          end if;
203
          dec_timeout_v := true;
204
        elsif pad_data_s /= '0' then
205
          cnt_ones_q  <= cnt_ones_q - 1;
206
        end if;
207
      end if;
208
 
209
      if cnt_ones_q < cnt_zeros_q then
210
        more_ones_q <= true;
211
      else
212
        more_ones_q <= false;
213
      end if;
214
 
215
      -- detect sample underflow
216
      sample_underflow_q <= dec_timeout_v;
217
 
218
      -- timeout counter
219
      if sync_timeout_s then
220
        -- explicit preload
221
        cnt_timeout_q <= cnt_timeout_high_c;
222
        timeout_q     <= false;
223
      elsif cnt_timeout_q = 0 then
224
        -- wrap-around
225
        cnt_timeout_q <= cnt_timeout_high_c;
226
        timeout_q     <= true;
227
      elsif dec_timeout_v then
228
        -- decrement counter when sampler wraps around
229
        cnt_timeout_q <= cnt_timeout_q - 1;
230
      end if;
231
 
232
 
233
      -- count remaining number of buttons to read
234
      if shift_buttons_s then
235
        shift_buttons_q(buttons_t'high downto 1) <= shift_buttons_q(buttons_t'high-1 downto 0);
236
 
237
        if more_ones_q then
238
          shift_buttons_q(0) <= '1';
239
        else
240
          shift_buttons_q(0) <= '0';
241
        end if;
242
 
243
      end if;
244
 
245
      if reset_num_buttons_s then
246
        -- explicit preload
247
        num_buttons_read_q   <= unsigned(rx_size_i);
248
      elsif shift_buttons_s then
249
        -- decrement counter when a button bit has been read
250
        if not all_buttons_read_s then
251
          num_buttons_read_q <= num_buttons_read_q - 1;
252
        end if;
253
      end if;
254
 
255
 
256
      -- the buttons
257
      if save_buttons_s then
258
        buttons_q <= shift_buttons_q;
259
      end if;
260
 
261
      if set_rx_done_s then
262
        rx_done_q <= true;
263
      else
264
        rx_done_q <= false;
265
      end if;
266
 
267
    end if;
268
 
269
  end process seq;
270
  --
271
  -----------------------------------------------------------------------------
272
 
273
  pad_data_s         <= pad_data_sync_q(1);
274
 
275
  -- indicates that all buttons have been read
276
  all_buttons_read_s <= num_buttons_read_q = 0;
277
 
278
 
279
  -----------------------------------------------------------------------------
280
  -- Process fsm
281
  --
282
  -- Purpose:
283
  --   Models the controlling state machine.
284
  --
285
  fsm: process (state_q,
286
                rx_en_i,
287
                pad_data_s,
288
                all_buttons_read_s,
289
                sampled_s,
290
                sample_underflow_q,
291
                timeout_q)
292
  begin
293
    sync_sample_s       <= false;
294
    sync_timeout_s      <= false;
295
    state_s             <= IDLE;
296
    shift_buttons_s     <= false;
297
    save_buttons_s      <= false;
298
    set_rx_done_s       <= false;
299
    reset_num_buttons_s <= false;
300
    wrap_sample_s       <= false;
301
 
302
    case state_q is
303
      -- IDLE -----------------------------------------------------------------
304
      -- The idle state.
305
      when IDLE =>
306
        if rx_en_i then
307
          state_s             <= DETECT_TIMEOUT;
308
 
309
        else
310
          -- keep counters synchronized when no reception is running
311
          sync_sample_s       <= true;
312
          sync_timeout_s      <= true;
313
          reset_num_buttons_s <= true;
314
          state_s             <= IDLE;
315
 
316
        end if;
317
 
318
      when DETECT_TIMEOUT =>
319
        state_s             <= DETECT_TIMEOUT;
320
 
321
        if pad_data_s = '0' then
322
          sync_sample_s     <= true;
323
          state_s           <= WAIT_FOR_1;
324
 
325
        else
326
          -- wait for timeout
327
          wrap_sample_s     <= true;
328
          if timeout_q then
329
            set_rx_done_s   <= true;
330
            state_s         <= IDLE;
331
          end if;
332
 
333
        end if;
334
 
335
 
336
      -- WAIT_FOR_1 -----------------------------------------------------------
337
      -- Sample counter has expired and a 0 bit has been detected.
338
      -- We must now wait for pad_data_s to become 1.
339
      -- Or abort upon timeout.
340
      when WAIT_FOR_1 =>
341
        if pad_data_s = '0' then
342
          if not sample_underflow_q then
343
            state_s       <= WAIT_FOR_1;
344
          else
345
            -- timeout while reading buttons!
346
            set_rx_done_s <= true;
347
            state_s       <= IDLE;
348
          end if;
349
 
350
        else
351
          state_s         <= WAIT_FOR_0;
352
        end if;
353
 
354
      -- WAIT_FOR_0 -----------------------------------------------------------
355
      -- pad_data_s is at 1 level now and no timeout occured so far.
356
      -- We wait for the next 0 level on pad_data_s or abort upon timeout.
357
      when WAIT_FOR_0 =>
358
        -- wait for falling edge of pad data
359
        if pad_data_s = '0' then
360
          sync_sample_s       <= true;
361
 
362
          if not all_buttons_read_s then
363
            -- loop another time if there are still some buttons to read
364
            shift_buttons_s   <= true;
365
            state_s           <= WAIT_FOR_1;
366
          else
367
            state_s           <= WAIT_FOR_0;
368
          end if;
369
 
370
        else
371
          if sample_underflow_q then
372
            if all_buttons_read_s then
373
              -- last button was read
374
              -- so it's ok to timeout
375
              state_s         <= FINISHED;
376
            else
377
              -- timeout while reading buttons!
378
              set_rx_done_s   <= true;
379
              state_s         <= IDLE;
380
            end if;
381
 
382
          else
383
            state_s           <= WAIT_FOR_0;
384
 
385
          end if;
386
 
387
        end if;
388
 
389
      when FINISHED =>
390
        -- finally save buttons
391
        save_buttons_s <= true;
392
        set_rx_done_s  <= true;
393
 
394
      when others =>
395
        null;
396
 
397
    end case;
398
 
399
  end process fsm;
400
  --
401
  -----------------------------------------------------------------------------
402
 
403
 
404
  -----------------------------------------------------------------------------
405
  -- Output Mapping
406
  -----------------------------------------------------------------------------
407
  rx_done_o   <= rx_done_q;
408
  but_a_o     <= buttons_q(pos_a_c);
409
  but_b_o     <= buttons_q(pos_b_c);
410
  but_x_o     <= buttons_q(pos_x_c);
411
  but_y_o     <= buttons_q(pos_y_c);
412
  but_z_o     <= buttons_q(pos_z_c);
413
  but_start_o <= buttons_q(pos_start_c);
414
  but_tl_o    <= buttons_q(pos_tl_c);
415
  but_tr_o    <= buttons_q(pos_tr_c);
416
  but_left_o  <= buttons_q(pos_left_c);
417
  but_right_o <= buttons_q(pos_right_c);
418
  but_up_o    <= buttons_q(pos_up_c);
419
  but_down_o  <= buttons_q(pos_down_c);
420
  ana_joy_x_o <= buttons_q(joy_x_high_c downto joy_x_low_c);
421
  ana_joy_y_o <= buttons_q(joy_y_high_c downto joy_y_low_c);
422
  ana_c_x_o   <= buttons_q(c_x_high_c   downto c_x_low_c);
423
  ana_c_y_o   <= buttons_q(c_y_high_c   downto c_y_low_c);
424
  ana_l_o     <= buttons_q(l_high_c     downto l_low_c);
425
  ana_r_o     <= buttons_q(r_high_c     downto r_low_c);
426
 
427
 
428
end rtl;
429
 
430
 
431
-------------------------------------------------------------------------------
432
-- File History:
433
--
434
-- $Log: not supported by cvs2svn $
435
-------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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