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

Subversion Repositories layer2

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 idiolatrie
--------------------------------------------------------------------------------
2
-- PS2 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
library ieee;
20
use ieee.std_logic_1164.all;
21
use ieee.numeric_std.all;
22
 
23
entity ps2 is
24
   port(
25
      clk      : in  std_logic;
26
      rst      : in  std_logic;
27
      PS2_CLK  : in  std_logic;
28
      PS2_DATA : in  std_logic;
29
      char     : out std_logic_vector(7 downto 0);
30
      rx_done  : out std_logic
31
   );
32
end ps2;
33
 
34
architecture rtl of ps2 is
35
 
36
   type ps2_state_t is (Start, Data, Parity, Stop, Ack);
37
 
38
   signal p, pin    : ps2_state_t := Start;
39
   signal s, sin    : std_logic_vector(7 downto 0);
40
   signal n, nin    : natural range 0 to 7;
41
   signal f, fin    : std_logic_vector(7 downto 0);
42
   signal t, tin    : std_logic;
43
   signal fall_edge : std_logic;
44
begin
45
 
46
   -----------------------------------------------------------------------------
47
   -- Input Signal Debounce                                                   --
48
   -----------------------------------------------------------------------------
49
   -- the frequency of the PS2 clock signal is about 20 to 30 KHz. To avoid   --
50
   -- undesired glitches, wait 8 cycles for a stable signal.                  --
51
   -----------------------------------------------------------------------------
52
   fin <= PS2_CLK & f(7 downto 1);
53
 
54
   tin <= '1' when f = x"FF" else
55
          '0' when f = x"00" else
56
          t;
57
 
58
     filter : process(clk)
59
   begin
60
      if rising_edge(clk) then
61
         f <= fin;
62
         t <= tin;
63
      end if;
64
   end process;
65
 
66
   fall_edge <= t and (not tin);
67
 
68
   -----------------------------------------------------------------------------
69
   -- PS2 Read                                                               --
70
   -----------------------------------------------------------------------------
71
   fsm : process(p, s, n, fall_edge, PS2_DATA)
72
   begin
73
 
74
      rx_done <= '0';
75
 
76
      pin <= p;
77
      sin <= s;
78
      nin <= n;
79
 
80
      case p is
81
 
82
         -- Wait for first falling edge. The first bit is a start bit with
83
         -- value '0'. We do not check that.
84
         when Start =>
85
            if fall_edge = '1' then
86
               nin <= 0;
87
               pin <= Data;
88
            end if;
89
 
90
         -- On the next 8 falling edges we shuffle data into the shift register.
91
         -- The keyboard sends the LSB first.
92
         when Data =>
93
            if fall_edge = '1' then
94
               sin <= PS2_DATA & s(7 downto 1);
95
               if n = 7 then
96
                  pin <= Parity;
97
               else
98
                  nin <= n + 1;
99
               end if;
100
            end if;
101
 
102
         -- Fetch odd parity bit. No parity check here.
103
         when Parity =>
104
            if fall_edge = '1' then
105
               sin <= PS2_DATA & s(7 downto 1);    -- A mystery.
106
               pin <= Stop;
107
            end if;
108
 
109
         -- Fetch stop bit. Always '1'.
110
         when Stop =>
111
            if fall_edge = '1' then
112
               pin <= Ack;
113
            end if;
114
 
115
         -- One cycle tick to indicate a complete reception.
116
         when Ack =>
117
            rx_done <= '1';
118
            pin     <= Start;
119
 
120
      end case;
121
   end process;
122
 
123
     reg : process(clk)
124
   begin
125
      if rising_edge(clk) then
126
         p <= pin;
127
         s <= sin;
128
         n <= nin;
129
         f <= fin;
130
 
131
         if rst = '1' then p <= Start; end if;
132
      end if;
133
   end process;
134
 
135
   char <= s;
136
end rtl;

powered by: WebSVN 2.1.0

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