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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [processor/] [VHDL/] [ext_modules/] [ext_key_matrix/] [key_matrix/] [key_matrix_beh.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 jlechner
-----------------------------------------------------------------------
2
-- This file is part of SCARTS.
3
-- 
4
-- SCARTS is free software: you can redistribute it and/or modify
5
-- it under the terms of the GNU General Public License as published by
6
-- the Free Software Foundation, either version 3 of the License, or
7
-- (at your option) any later version.
8
-- 
9
-- SCARTS is distributed in the hope that it will be useful,
10
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
11
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
-- GNU General Public License for more details.
13
-- 
14
-- You should have received a copy of the GNU General Public License
15
-- along with SCARTS.  If not, see <http://www.gnu.org/licenses/>.
16
-----------------------------------------------------------------------
17
 
18
 
19
library ieee;
20
use ieee.std_logic_1164.all;
21
use ieee.numeric_std.all;
22
use work.debounce_pkg.all;
23
 
24
architecture beh of key_matrix is
25
  constant CLK_PERIOD : time := 1E9 / CLK_FREQ * 1 ns;
26
  constant CNT_MAX : integer := SCAN_TIME_INTERVAL / CLK_PERIOD;
27
 
28
  signal rows_debounced : std_logic_vector(ROW_COUNT - 1 downto 0);
29
  type debounce_signal_array is array(0 to COLUMN_COUNT - 1, ROW_COUNT - 1 downto 0) of std_logic;
30
  signal rows_debounced_old, rows_debounced_old_next : debounce_signal_array;
31
  signal debouncer_reinit : std_logic;
32
  signal debouncer_reinit_value : std_logic_vector(ROW_COUNT - 1 downto 0);
33
  type KEY_MATRIX_STATE_TYPE is (STATE_FIRST_COLUMN, STATE_NEXT_COLUMN, STATE_REINIT_DEBOUNCER, STATE_EXECUTE);
34
  signal key_matrix_state, key_matrix_state_next : KEY_MATRIX_STATE_TYPE;
35
  signal interval, interval_next : integer range 0 to CNT_MAX;
36
  signal current_column, current_column_next : integer range 0 to COLUMN_COUNT - 1;
37
  signal key_next : std_logic_vector(log2c(ROW_COUNT * COLUMN_COUNT) - 1 downto 0);
38
  signal decode_data : std_logic;
39
begin
40
  process(current_column)
41
  begin
42
    columns <= (others => '0');
43
    columns(current_column) <= '1';
44
  end process;
45
 
46
  debouncer_gen : for i in 0 to ROW_COUNT - 1 generate
47
    debouncer_inst : debounce
48
      generic map
49
      (
50
        CLK_FREQ => CLK_FREQ,
51
        SYNC_STAGES => SYNC_STAGES,
52
        TIMEOUT => DEBOUNCE_TIMEOUT
53
      )
54
      port map
55
      (
56
        sys_clk => sys_clk,
57
        sys_res_n => sys_res_n,
58
        data_in => rows(i),
59
        data_out => rows_debounced(i),
60
        reinit => debouncer_reinit,
61
        reinit_value => debouncer_reinit_value(i)
62
      );
63
  end generate debouncer_gen;
64
 
65
  process(key_matrix_state, interval, current_column)
66
  begin
67
    key_matrix_state_next <= key_matrix_state;
68
 
69
    case key_matrix_state is
70
      when STATE_FIRST_COLUMN =>
71
        key_matrix_state_next <= STATE_REINIT_DEBOUNCER;
72
      when STATE_NEXT_COLUMN =>
73
        key_matrix_state_next <= STATE_REINIT_DEBOUNCER;
74
      when STATE_REINIT_DEBOUNCER =>
75
        key_matrix_state_next <= STATE_EXECUTE;
76
      when STATE_EXECUTE =>
77
        if interval = CNT_MAX - 1 then
78
          if current_column = COLUMN_COUNT - 1 then
79
            key_matrix_state_next <= STATE_FIRST_COLUMN;
80
          else
81
            key_matrix_state_next <= STATE_NEXT_COLUMN;
82
          end if;
83
        end if;
84
    end case;
85
  end process;
86
 
87
  process(key_matrix_state, interval, current_column, rows_debounced, rows_debounced_old)
88
  begin
89
    current_column_next <= current_column;
90
    debouncer_reinit <= '0';
91
    debouncer_reinit_value <= (others => '0');
92
    rows_debounced_old_next <= rows_debounced_old;
93
    interval_next <= 0;
94
    decode_data <= '0';
95
 
96
    case key_matrix_state is
97
      when STATE_FIRST_COLUMN =>
98
        current_column_next <= 0;
99
      when STATE_NEXT_COLUMN =>
100
        current_column_next <= current_column + 1;
101
      when STATE_REINIT_DEBOUNCER =>
102
        debouncer_reinit <= '1';
103
        for i in 0 to ROW_COUNT - 1 loop
104
          debouncer_reinit_value(i) <= rows_debounced_old(current_column, i);
105
        end loop;
106
      when STATE_EXECUTE =>
107
        interval_next <= interval + 1;
108
        for i in 0 to ROW_COUNT - 1 loop
109
          rows_debounced_old_next(current_column, i) <= rows_debounced(i);
110
        end loop;
111
        decode_data <= '1';
112
    end case;
113
  end process;
114
 
115
  process(sys_clk, sys_res_n)
116
  begin
117
    if sys_res_n = '0' then
118
      current_column <= 0;
119
      rows_debounced_old <= (others => (others => '0'));
120
      interval <= 0;
121
      key_matrix_state <= STATE_FIRST_COLUMN;
122
      key <= (others => '0');
123
    elsif rising_edge(sys_clk) then
124
      current_column <= current_column_next;
125
      interval <= interval_next;
126
      rows_debounced_old <= rows_debounced_old_next;
127
      key_matrix_state <= key_matrix_state_next;
128
      key <= key_next;
129
    end if;
130
  end process;
131
 
132
  process(decode_data, rows_debounced, rows_debounced_old, current_column)
133
    variable key_int : integer range 0 to ROW_COUNT * COLUMN_COUNT;
134
    variable found, valid : boolean;
135
  begin
136
    key_next <= (others => '0');
137
 
138
    if decode_data = '1' then
139
      key_int := 0;
140
      found := false;
141
      valid := true;
142
      for i in 0 to ROW_COUNT - 1 loop
143
        if rows_debounced(i) = '1' then
144
          if found = true then -- Only one key may be pressed at once
145
            valid := false;
146
          end if;
147
          if rows_debounced_old(current_column, i) = '1' then -- Only valid the first time the key is pressed
148
            valid := false;
149
          end if;
150
          found := true;
151
        end if;
152
        -- Calculate the key number (i * COLUMN_COUNT)
153
        -- = Addition of column count until the key is found
154
        if not found then
155
          key_int := key_int + COLUMN_COUNT;
156
        end if;
157
      end loop;
158
      if valid and found then
159
        -- If a valid key was found, correct the key number to the correct column
160
        key_int := key_int + current_column + 1;
161
      else
162
        key_int := 0;
163
      end if;
164
      key_next <= std_logic_vector(to_unsigned(key_int, log2c(ROW_COUNT * COLUMN_COUNT)));
165
    end if;
166
  end process;
167
end architecture beh;

powered by: WebSVN 2.1.0

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