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

Subversion Repositories layer2

[/] [layer2/] [trunk/] [vhdl/] [keyb/] [rtl/] [keyb.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 idiolatrie
--------------------------------------------------------------------------------
2
-- PS2 Keyboard Controller                                                    --
3
--------------------------------------------------------------------------------
4
-- Copyright (C)2011  Mathias Hörtnagl <mathias.hoertnagl@gmail.comt>         --
5
--                                                                            --
6
-- This program is free software: you can redistribute it and/or modify       --
7
-- it under the terms of the GNU General Public License as published by       --
8
-- the Free Software Foundation, either version 3 of the License, or          --
9
-- (at your option) any later version.                                        --
10
--                                                                            --
11
-- This program is distributed in the hope that it will be useful,            --
12
-- but WITHOUT ANY WARRANTY; without even the implied warranty of             --
13
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              --
14
-- GNU General Public License for more details.                               --
15
--                                                                            --
16
-- You should have received a copy of the GNU General Public License          --
17
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.      --
18
--------------------------------------------------------------------------------
19
-- http://www.computer-engineering.org/ps2keyboard/
20
library ieee;
21
use ieee.std_logic_1164.all;
22
use ieee.numeric_std.all;
23
 
24
library work;
25
use work.iwb.all;
26
 
27
entity keyb is
28
   port(
29
      si        : in  slave_in_t;
30
      so        : out slave_out_t;
31
   -- Non-Wishbone Signals
32
      PS2_CLK   : in  std_logic;
33
      PS2_DATA  : in  std_logic;
34
      intr      : out std_logic
35
   );
36
end keyb;
37
 
38
architecture rtl of keyb is
39
 
40
   constant EXTENDED_CODE : std_logic_vector(7 downto 0) := x"E0";
41
   constant BREAK_CODE    : std_logic_vector(7 downto 0) := x"F0";
42
   constant CAPS          : std_logic_vector(7 downto 0) := x"58";
43
   constant LEFT_SHIFT    : std_logic_vector(7 downto 0) := x"12";
44
   constant RIGHT_SHIFT   : std_logic_vector(7 downto 0) := x"59";
45
   constant LEFT_CTRL     : std_logic_vector(7 downto 0) := x"14";
46
   constant LEFT_ALT      : std_logic_vector(7 downto 0) := x"11";
47
   constant RIGHT_CTRL    : std_logic_vector(7 downto 0) := x"14";
48
   constant RIGHT_ALT     : std_logic_vector(7 downto 0) := x"11";
49
 
50
   component ps2 is
51
      port(
52
         clk      : in  std_logic;
53
         rst      : in  std_logic;
54
         PS2_CLK  : in  std_logic;
55
         PS2_DATA : in  std_logic;
56
         char     : out std_logic_vector(7 downto 0);
57
         rx_done  : out std_logic
58
      );
59
   end component;
60
 
61
   component ascii is
62
      port(
63
         clk   : in  std_logic;
64
         shft  : in  std_logic;
65
         altgr : in std_logic;
66
         code  : in  std_logic_vector(7 downto 0);
67
         char  : out std_logic_vector(7 downto 0)
68
      );
69
   end component;
70
 
71
   attribute RAM_STYLE : string;
72
   attribute RAM_STYLE of ascii : component is "BLOCK";
73
 
74
   type state_t is (Idle, ExtCode, BrkCode, ExtRelease, Translate, Check,
75
                    Ack, Ack2);
76
 
77
   type char_t is record
78
      shft  : std_logic;                           -- Shift key.
79
      cps   : std_logic;                           -- Caps key.
80
      ctrl  : std_logic;                           -- Control key.
81
      alt   : std_logic;                           -- Alt key.
82
      altgr : std_logic;                           -- Alt Gr key.
83
      m     : std_logic_vector(7 downto 0);        -- Scan code.
84
   end record;
85
 
86
   signal k, kin   : state_t := Idle;              -- Keyboard controller state.
87
   signal c, cin   : char_t;                       -- Character structure.
88
   signal code     : std_logic_vector(7 downto 0); -- PS2 scan code.
89
   signal char     : std_logic_vector(7 downto 0); -- ASCII character.
90
   signal shftcps  : std_logic;                    -- SHIFT xor CAPS.
91
   signal rx_done  : std_logic;                    -- PS2 receive done tick.
92
   signal key_done : std_logic;                    -- Keyboard ctrl done tick.
93
begin
94
 
95
   -----------------------------------------------------------------------------
96
   -- PS2 Controller                                                          --
97
   -----------------------------------------------------------------------------
98
   ps2_ctrl : ps2 port map(
99
      clk      => si.clk,
100
      rst      => si.rst,
101
      PS2_CLK  => PS2_CLK,
102
      PS2_DATA => PS2_DATA,
103
      char     => code,
104
      rx_done  => rx_done
105
   );
106
 
107
   -----------------------------------------------------------------------------
108
   -- ScanCode To ASCII ROM                                                   --
109
   -----------------------------------------------------------------------------
110
   shftcps <= c.shft xor c.cps;     -- If both are set, turn to lower case.
111
 
112
   ascii_rom : ascii port map(
113
      clk   => si.clk,
114
      shft  => shftcps,
115
      altgr => c.altgr,
116
      code  => c.m,
117
      char  => char
118
   );
119
 
120
   -----------------------------------------------------------------------------
121
   -- Keyboard Control                                                        --
122
   -----------------------------------------------------------------------------
123
   key : process(k, c, rx_done, code, si.stb, si.we, si, char)
124
   begin
125
 
126
      kin <= k;
127
      cin <= c;
128
 
129
      intr   <= '0';
130
      so.ack <= '0';
131
      --key_done <= '0';  
132
 
133
      case k is
134
 
135
         -- Wait for some key input.
136
         when Idle =>
137
            if rx_done = '1' then
138
               case code is
139
 
140
                  when EXTENDED_CODE =>
141
                     kin   <= ExtCode;
142
 
143
                  when BREAK_CODE =>
144
                     kin   <= BrkCode;
145
 
146
                  -- User pressed a functional key. Just latch and then return
147
                  -- to Idle state. The CPU does not need to be bothered.
148
                  when LEFT_SHIFT | RIGHT_SHIFT =>
149
                     cin.shft <= '1';
150
                     kin      <= Idle;
151
                  when CAPS =>
152
                     cin.cps  <= not c.cps;
153
                     kin      <= Idle;
154
                  when LEFT_CTRL =>
155
                     cin.ctrl <= '1';
156
                     kin      <= Idle;
157
                  when LEFT_ALT =>
158
                     cin.alt  <= '1';
159
                     kin      <= Idle;
160
 
161
                  -- The actual key code.
162
                  when others =>
163
                     cin.m <= code;
164
                     kin   <= Translate;
165
               end case;
166
            end if;
167
 
168
         -- PREVIOUS STATE: Idle.
169
         when ExtCode =>
170
            if rx_done = '1' then
171
               case code is
172
 
173
                  -- If we receive a BREAK CODE we know that the following
174
                  -- pressed key (represented by the next byte) has been
175
                  -- released.
176
                  when BREAK_CODE =>
177
                     kin   <= ExtRelease;
178
 
179
                  -- The RIGHT CTRL and RIGHT ALT (ALT GR) are the same key
180
                  -- codes as LEFT CTRL and LEFT ALT plus an preceeding EXTENDED
181
                  -- CODE. RIGHT ALT (ALT GR) has a different functional
182
                  -- meaning.
183
                  when RIGHT_CTRL =>
184
                     cin.ctrl  <= '1';
185
                     kin       <= Idle;
186
                  when RIGHT_ALT =>
187
                     cin.altgr <= '1';
188
                     kin       <= Idle;
189
 
190
                  -- Once more the actual key code.
191
                  when others =>
192
                     cin.m <= code;
193
                     kin   <= Translate;
194
               end case;
195
            end if;
196
 
197
         -- PREVIOUS STATE: Idle.
198
         when BrkCode =>
199
            if rx_done = '1' then
200
               case code is
201
 
202
                  -- A functional key has been released.
203
                  when LEFT_SHIFT | RIGHT_SHIFT =>
204
                     cin.shft <= '0';
205
                     kin      <= Idle;
206
                  when LEFT_CTRL =>
207
                     cin.ctrl <= '0';
208
                     kin      <= Idle;
209
                  when LEFT_ALT =>
210
                     cin.alt  <= '0';
211
                     kin      <= Idle;
212
 
213
                  -- Do nothing when CAPS is released.
214
                  when CAPS =>
215
                     kin <= Idle;
216
 
217
                  -- Do nothing on key release.
218
                  when others =>
219
                     kin <= Idle;
220
               end case;
221
            end if;
222
 
223
         -- PREVIOUS STATE: ExtCode.
224
         -- Either turn off the RIGHT CTRL or RIGHT ALT flags, or receive a non
225
         -- functional key code release.
226
         when ExtRelease =>
227
            if rx_done = '1' then
228
               case code is
229
 
230
                  -- The RIGHT CTRL and RIGHT ALT (ALT GR) are the same key
231
                  -- codes as LEFT CTRL and LEFT ALT plus an preceeding EXTENDED
232
                  -- CODE. RIGHT ALT (ALT GR) has a different functional
233
                  -- meaning.
234
                  when RIGHT_CTRL =>
235
                     cin.ctrl <= '0';
236
                     kin      <= Idle;
237
                  when RIGHT_ALT =>
238
                     cin.altgr <= '0';
239
                     kin       <= Idle;
240
 
241
                  -- Do nothing on key release.
242
                  when others =>
243
                     kin   <= Idle;
244
               end case;
245
            end if;
246
 
247
         -- PREVIOUS STATES: Idle, ExtCode.
248
         -- One cycle delay for the ASCII-ROM to translate the keyboard code.
249
         when Translate =>
250
            kin <= Check;
251
 
252
         -- Ignore all undefined keys.
253
         when Check =>
254
            if char = x"00" then
255
               kin <= Idle;
256
            else
257
               kin <= Ack;
258
            end if;
259
 
260
         -- Wait for a Wishbone read, set interrrupt meanwhile.
261
         when Ack =>
262
            intr <= '1';
263
            if wb_read(si) then
264
               so.ack <= '1';
265
               --key_done <= '1';
266
               kin      <= Ack2;
267
            end if;
268
 
269
         -- Wait and hold done signal until master notices ack signal and pulls
270
         -- stb down.
271
         when Ack2 =>
272
            intr   <= '1';
273
            so.ack <= '1';
274
            --key_done <= '1';
275
            if si.stb = '0' then
276
               kin <= Idle;
277
            end if;
278
 
279
      end case;
280
   end process;
281
 
282
   so.dat <= x"0000" & c.shft & c.ctrl & c.alt & c.altgr & x"0" & char;
283
   --so.ack <= key_done;
284
 
285
   -----------------------------------------------------------------------------
286
   -- Registers                                                               --
287
   -----------------------------------------------------------------------------
288
     reg : process(si.clk)
289
   begin
290
      if rising_edge(si.clk) then
291
         k <= kin;
292
         c <= cin;
293
         if si.rst = '1' then
294
            k <= Idle;
295
            c <= ('0','0','0','0','0',(others => '-'));
296
         end if;
297
      end if;
298
   end process;
299
end rtl;

powered by: WebSVN 2.1.0

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