Aktuální adresář: FITkit /
trunk /
fpga /
ctrls /
keyboard /
keyboard_ctrl.vhd
1 -- keyboard_ctrl.vhd : Keyboard controller
2 -- Copyright (C) 2006 Brno University of Technology,
3 -- Faculty of Information Technology
4 -- Author(s): Zdenek Vasicek <xvasic11 AT stud.fit.vutbr.cz>
5 --
6 -- LICENSE TERMS
7 --
8 -- Redistribution and use in source and binary forms, with or without
9 -- modification, are permitted provided that the following conditions
10 -- are met:
11 -- 1. Redistributions of source code must retain the above copyright
12 -- notice, this list of conditions and the following disclaimer.
13 -- 2. Redistributions in binary form must reproduce the above copyright
14 -- notice, this list of conditions and the following disclaimer in
15 -- the documentation and/or other materials provided with the
16 -- distribution.
17 -- 3. All advertising materials mentioning features or use of this software
18 -- or firmware must display the following acknowledgement:
19 --
20 -- This product includes software developed by the University of
21 -- Technology, Faculty of Information Technology, Brno and its
22 -- contributors.
23 --
24 -- 4. Neither the name of the Company nor the names of its contributors
25 -- may be used to endorse or promote products derived from this
26 -- software without specific prior written permission.
27 --
28 -- This software or firmware is provided ``as is'', and any express or implied
29 -- warranties, including, but not limited to, the implied warranties of
30 -- merchantability and fitness for a particular purpose are disclaimed.
31 -- In no event shall the company or contributors be liable for any
32 -- direct, indirect, incidental, special, exemplary, or consequential
33 -- damages (including, but not limited to, procurement of substitute
34 -- goods or services; loss of use, data, or profits; or business
35 -- interruption) however caused and on any theory of liability, whether
36 -- in contract, strict liability, or tort (including negligence or
37 -- otherwise) arising in any way out of the use of this software, even
38 -- if advised of the possibility of such damage.
39 --
40 -- $Id$
41 --
42 --
43 -- Description:
44 --
45 -- KEYBOARD
46 --
47 -- +---+---+---+---+
48 -- KB_KIN(0) ---->| 1 | 2 | 3 | A |
49 -- +---+---+---+---+
50 -- KB_KIN(1) ---->| 4 | 5 | 6 | B |
51 -- +---+---+---+---+
52 -- KB_KIN(2) ---->| 7 | 8 | 9 | C |
53 -- +---+---+---+---+
54 -- KB_KIN(3) ---->| * | 0 | # | D |
55 -- +---+---+---+---+
56 -- | | | |
57 -- KB_KOUT(0) <----+ | | |
58 -- KB_KOUT(1) <--------+ | |
59 -- KB_KOUT(2) <------------+ |
60 -- KB_KOUT(3) <----------------+
61 --
62 -- meaning of DATA_OUT
63 -- DATA_OUT(0) <=> '1'
64 -- DATA_OUT(1) <=> '4'
65 -- DATA_OUT(2) <=> '7'
66 -- DATA_OUT(3) <=> '*'
67 -- DATA_OUT(4) <=> '2'
68 -- DATA_OUT(5) <=> '5'
69 -- DATA_OUT(6) <=> '8'
70 -- DATA_OUT(7) <=> '0'
71 -- DATA_OUT(8) <=> '3'
72 -- DATA_OUT(9) <=> '6'
73 -- DATA_OUT(10) <=> '9'
74 -- DATA_OUT(11) <=> '#'
75 -- DATA_OUT(12) <=> 'A'
76 -- DATA_OUT(13) <=> 'B'
77 -- DATA_OUT(14) <=> 'C'
78 -- DATA_OUT(15) <=> 'D'
79 --
80
81
82 library IEEE;
83 use IEEE.STD_LOGIC_1164.ALL;
84 use IEEE.STD_LOGIC_ARITH.ALL;
85 use IEEE.STD_LOGIC_UNSIGNED.ALL;
86
87 -- SYNTH-ISE-8.2: slices=27, slicesFF=36, 4luts=53
88 entity keyboard_controller is
89 generic(
90 READ_INTERVAL : integer := (2**14)-1
91 );
92 port(
93 -- Hodiny
94 CLK : in std_logic;
95 -- Reset
96 RST : in std_logic;
97
98 -- Stisknute klavesy
99 DATA_OUT : out std_logic_vector(15 downto 0);
100 DATA_VLD : out std_logic;
101
102 -- Signaly klavesnice
103 KB_KIN : out std_logic_vector(3 downto 0);
104 KB_KOUT : in std_logic_vector(3 downto 0)
105 );
106 end keyboard_controller;
107
108 architecture arch_keyboard of keyboard_controller is
109
110 type FSMstate is (SInit, SScan0, SScan1, SScan2, SScan3, SWE);
111
112 signal pstate : FSMstate; -- actual state
113 signal nstate : FSMstate; -- next state
114
115 signal data_reg : std_logic_vector(15 downto 0);
116 signal data_mx : std_logic_vector(3 downto 0);
117 signal data_sel : std_logic_vector(1 downto 0);
118 signal data_cmp : std_logic;
119
120 signal cntr_reg : std_logic_vector(14 downto 0);
121 signal cntr_zero: std_logic;
122
123 signal kb_we : std_logic_vector(3 downto 0);
124 signal kbout : std_logic_vector(3 downto 0);
125
126 signal eq_reg : std_logic;
127 signal eq_rst : std_logic;
128 signal eq_en : std_logic;
129
130 begin
131
132 DATA_OUT <= data_reg;
133
134 -- Interval counter
135 intervalcounter: process (RST, CLK)
136 begin
137 if (RST = '1') then
138 cntr_reg <= (others => '0');
139 elsif (CLK'event) and (CLK = '1') then
140 if (cntr_zero='1') then
141 cntr_reg <= (others => '0');
142 else
143 cntr_reg <= cntr_reg + 1;
144 end if;
145 end if;
146 end process;
147 cntr_zero <= '1' when (cntr_reg=conv_std_logic_vector(READ_INTERVAL, cntr_reg'length))
148 else '0';
149
150 -- Activation of rows
151 -- in order to avoid shorts due to missing diodes, we use 'Z'
152 KB_KIN(0) <= '0' when kb_we(0) = '1' else 'Z';
153 KB_KIN(1) <= '0' when kb_we(1) = '1' else 'Z';
154 KB_KIN(2) <= '0' when kb_we(2) = '1' else 'Z';
155 KB_KIN(3) <= '0' when kb_we(3) = '1' else 'Z';
156
157 kbout <= not KB_KOUT;
158
159 -- Data registers
160 dregs: process (RST, CLK)
161 begin
162 if (RST = '1') then
163 data_reg <= (others => '0');
164 elsif (CLK'event) and (CLK = '1') then
165 if (kb_we(0) = '1') then
166 data_reg(3 downto 0) <= kbout;
167 end if;
168 if (kb_we(1) = '1') then
169 data_reg(7 downto 4) <= kbout;
170 end if;
171 if (kb_we(2) = '1') then
172 data_reg(11 downto 8) <= kbout;
173 end if;
174 if (kb_we(3) = '1') then
175 data_reg(15 downto 12) <= kbout;
176 end if;
177 end if;
178 end process;
179
180 data_mx <= data_reg(3 downto 0) when data_sel="00" else
181 data_reg(7 downto 4) when data_sel="01" else
182 data_reg(11 downto 8) when data_sel="10" else
183 data_reg(15 downto 12);
184
185 data_cmp <= '1' when (data_mx = kbout) else '0';
186
187 -- Register that hold changes
188 process (RST, CLK)
189 begin
190 if (RST = '1') then
191 eq_reg <= '1';
192 elsif (CLK'event) and (CLK = '1') then
193 if (eq_rst='1') then
194 eq_reg <= '1';
195 elsif (eq_en='1') then
196 eq_reg <= eq_reg and data_cmp;
197 end if;
198 end if;
199 end process;
200
201 --FSM actual state
202 process (RST, CLK)
203 begin
204 if (RST = '1') then
205 pstate <= SInit;
206 elsif (CLK'event) and (CLK = '1') then
207 pstate <= nstate;
208 end if;
209 end process;
210
211 --FSM next state logic
212 process (pstate, cntr_zero, eq_reg)
213 begin
214 nstate <= SInit;
215 kb_we <= "0000";
216 data_sel <= "00";
217 DATA_VLD <= '0';
218 eq_rst <= '0';
219 eq_en <= '0';
220
221 case pstate is
222 when SInit =>
223 if (cntr_zero='1') then
224 nstate <= SScan0;
225 eq_rst <= '1';
226 end if;
227
228 --Scan
229 when SScan0 =>
230 nstate <= SScan1;
231 data_sel <= "00";
232 kb_we(0) <= '1';
233 eq_en <= '1';
234
235 when SScan1 =>
236 nstate <= SScan2;
237 data_sel <= "01";
238 kb_we(1) <= '1';
239 eq_en <= '1';
240
241 when SScan2 =>
242 nstate <= SScan3;
243 data_sel <= "10";
244 kb_we(2) <= '1';
245 eq_en <= '1';
246
247 when SScan3 =>
248 nstate <= SWE;
249 data_sel <= "11";
250 kb_we(3) <= '1';
251 eq_en <= '1';
252
253 --Write enable
254 when SWE =>
255 DATA_VLD <= not eq_reg;
256
257 when others =>
258 null;
259 end case;
260 end process;
261
262 end arch_keyboard;
263