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

Subversion Repositories zx_ula

[/] [zx_ula/] [branches/] [xilinx/] [spectrum_48k_spartan3a_for_gameduino_mod_vga_timex_hicolor_ulaplus/] [ps2_intf.vhd] - Blame information for rev 29

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 29 mcleod_ide
-- ZX Spectrum for Altera DE1
2
--
3
-- Copyright (c) 2009-2011 Mike Stirling
4
--
5
-- All rights reserved
6
--
7
-- Redistribution and use in source and synthezised forms, with or without
8
-- modification, are permitted provided that the following conditions are met:
9
--
10
-- * Redistributions of source code must retain the above copyright notice,
11
--   this list of conditions and the following disclaimer.
12
--
13
-- * Redistributions in synthesized form must reproduce the above copyright
14
--   notice, this list of conditions and the following disclaimer in the
15
--   documentation and/or other materials provided with the distribution.
16
--
17
-- * Neither the name of the author nor the names of other contributors may
18
--   be used to endorse or promote products derived from this software without
19
--   specific prior written agreement from the author.
20
--
21
-- * License is granted for non-commercial use only.  A fee may not be charged
22
--   for redistributions as source code or in synthesized/hardware form without 
23
--   specific prior written agreement from the author.
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
 
38
-- PS/2 interface (input only)
39
-- Based loosely on ps2_ctrl.vhd (c) ALSE. http://www.alse-fr.com
40
library IEEE;
41
use IEEE.STD_LOGIC_1164.ALL;
42
use IEEE.STD_LOGIC_ARITH.ALL;
43
use IEEE.STD_LOGIC_UNSIGNED.ALL;
44
 
45
-- This is input-only for the time being
46
entity ps2_intf is
47
generic (filter_length : positive := 8);
48
port(
49
        CLK                     :       in      std_logic;
50
        nRESET          :       in      std_logic;
51
 
52
        -- PS/2 interface (could be bi-dir)
53
        PS2_CLK         :       in      std_logic;
54
        PS2_DATA        :       in      std_logic;
55
 
56
        -- Byte-wide data interface - only valid for one clock
57
        -- so must be latched externally if required
58
        DATA            :       out     std_logic_vector(7 downto 0);
59
        VALID           :       out     std_logic;
60
        ERROR           :       out     std_logic
61
        );
62
end ps2_intf;
63
 
64
architecture ps2_intf_arch of ps2_intf is
65
subtype filter_t is std_logic_vector(filter_length-1 downto 0);
66
signal  clk_filter      :       filter_t;
67
 
68
signal  ps2_clk_in      :       std_logic;
69
signal  ps2_dat_in      :       std_logic;
70
-- Goes high when a clock falling edge is detected
71
signal  clk_edge        :       std_logic;
72
signal  bit_count       :       unsigned (3 downto 0);
73
signal  shiftreg        :       std_logic_vector(8 downto 0);
74
signal  parity          :       std_logic;
75
begin
76
        -- Register input signals
77
        process(nRESET,CLK)
78
        begin
79
                if nRESET = '0' then
80
                        ps2_clk_in <= '1';
81
                        ps2_dat_in <= '1';
82
                        clk_filter <= (others => '1');
83
                        clk_edge <= '0';
84
                elsif rising_edge(CLK) then
85
                        -- Register inputs (and filter clock)
86
                        ps2_dat_in <= PS2_DATA;
87
                        clk_filter <= PS2_CLK & clk_filter(clk_filter'high downto 1);
88
                        clk_edge <= '0';
89
 
90
                        if clk_filter = filter_t'(filter_length-1 downto 0 => '1') then
91
                                -- Filtered clock is high
92
                                ps2_clk_in <= '1';
93
                        elsif clk_filter = filter_t'(filter_length-1 downto 0 => '0') then
94
                                -- Filter clock is low, check for edge
95
                                if ps2_clk_in = '1' then
96
                                        clk_edge <= '1';
97
                                end if;
98
                                ps2_clk_in <= '0';
99
                        end if;
100
                end if;
101
        end process;
102
 
103
        -- Shift in keyboard data
104
        process(nRESET,CLK)
105
        begin
106
                if nRESET = '0' then
107
                        bit_count <= (others => '0');
108
                        shiftreg <= (others => '0');
109
                        parity <= '0';
110
                        DATA <= (others => '0');
111
                        VALID <= '0';
112
                        ERROR <= '0';
113
                elsif rising_edge(CLK) then
114
                        -- Clear flags
115
                        VALID <= '0';
116
                        ERROR <= '0';
117
 
118
                        if clk_edge = '1' then
119
                                -- We have a new bit from the keyboard for processing
120
                                if bit_count = 0 then
121
                                        -- Idle state, check for start bit (0) only and don't
122
                                        -- start counting bits until we get it
123
 
124
                                        parity <= '0';
125
 
126
                                        if ps2_dat_in = '0' then
127
                                                -- This is a start bit
128
                                                bit_count <= bit_count + 1;
129
                                        end if;
130
                                else
131
                                        -- Running.  8-bit data comes in LSb first followed by
132
                                        -- a single stop bit (1)
133
                                        if bit_count < 10 then
134
                                                -- Shift in data and parity (9 bits)
135
                                                bit_count <= bit_count + 1;
136
                                                shiftreg <= ps2_dat_in & shiftreg(shiftreg'high downto 1);
137
                                                parity <= parity xor ps2_dat_in; -- Calculate parity
138
                                        elsif ps2_dat_in = '1' then
139
                                                -- Valid stop bit received
140
                                                bit_count <= (others => '0'); -- back to idle
141
                                                if parity = '1' then
142
                                                        -- Parity correct, submit data to host
143
                                                        DATA <= shiftreg(7 downto 0);
144
                                                        VALID <= '1';
145
                                                else
146
                                                        -- Error
147
                                                        ERROR <= '1';
148
                                                end if;
149
                                        else
150
                                                -- Invalid stop bit
151
                                                bit_count <= (others => '0'); -- back to idle
152
                                                ERROR <= '1';
153
                                        end if;
154
                                end if;
155
                        end if;
156
                end if;
157
        end process;
158
end ps2_intf_arch;

powered by: WebSVN 2.1.0

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