OpenCores
URL https://opencores.org/ocsvn/forth-cpu/forth-cpu/trunk

Subversion Repositories forth-cpu

[/] [forth-cpu/] [trunk/] [kbd.vhd] - Diff between revs 3 and 5

Only display areas with differences | Details | Blame | View Log

Rev 3 Rev 5
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--
--
--    FileName:         kbd.vhd
--    FileName:         kbd.vhd
--    Dependencies:     debounce.vhd
--    Dependencies:     debounce.vhd
--    Design Software:  Quartus II 32-bit Version 12.1 Build 177 SJ Full Version
--    Design Software:  Quartus II 32-bit Version 12.1 Build 177 SJ Full Version
--
--
--    HDL CODE is PROVIDED "AS IS."  DIGI-KEY EXPRESSLY DISCLAIMS ANY
--    HDL CODE is PROVIDED "AS IS."  DIGI-KEY EXPRESSLY DISCLAIMS ANY
--    WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
--    WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
--    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
--    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
--    PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
--    PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
--    BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
--    BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
--    DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
--    DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
--    PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
--    PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
--    BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
--    BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
--    ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
--    ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
--
--
--    Version History
--    Version History
--    Version 1.0 11/29/2013 Scott Larson
--    Version 1.0 11/29/2013 Scott Larson
--      Initial Public Release
--      Initial Public Release
--
--
--  See https://eewiki.net/pages/viewpage.action?pageId=28279002
--  See https://eewiki.net/pages/viewpage.action?pageId=28279002
--
--
--  @note This file has been renamed and updated from the original.
--  @note This file has been renamed and updated from the original.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
library ieee;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
 
use work.util.common_generics;
 
 
package kbd_pkg is
package kbd_pkg is
 
 
        component ps2_kbd_top is
        component ps2_kbd_top is
                generic(
                generic(
                        clock_frequency:           integer := 50000000; -- system clock frequency in hz
                        clock_frequency:           integer := 50000000; -- system clock frequency in Hz
                        ps2_debounce_counter_size: integer := 8);       -- set such that 2^size/clock_frequency = 5us (size = 8 for 50mhz)
                        ps2_debounce_counter_size: integer := 8);       -- set such that 2^size/clock_frequency = 5us (size = 8 for 50MHz)
                port(
                port(
                        clk:        in  std_ulogic;                     -- system clock input
                        clk:        in  std_ulogic;                     -- system clock input
                        ps2_clk:    in  std_ulogic;                     -- clock signal from PS2 keyboard
                        ps2_clk:    in  std_ulogic;                     -- clock signal from PS2 keyboard
                        ps2_data:   in  std_ulogic;                     -- data signal from PS2 keyboard
                        ps2_data:   in  std_ulogic;                     -- data signal from PS2 keyboard
                        ascii_new:  out std_ulogic := '0';              -- output flag indicating new ascii value
                        ascii_new:  out std_ulogic := '0';              -- output flag indicating new ascii value
                        ascii_code: out std_ulogic_vector(6 downto 0)); -- ASCII value
                        ascii_code: out std_ulogic_vector(6 downto 0)); -- ASCII value
        end component;
        end component;
 
 
        component ps2_kbd_core is
        component ps2_kbd_core is
        generic(
        generic(
                clock_frequency: integer := 50000000;  -- system clock frequency in hz
                clock_frequency: integer := 50000000;  -- system clock frequency in Hz
                debounce_counter_size: integer := 8);  -- set such that (2^size)/clock_frequency = 5us (size = 8 for 50mhz)
                debounce_counter_size: integer := 8);  -- set such that (2^size)/clock_frequency = 5us (size = 8 for 50MHz)
        port(
        port(
                clk:          in  std_ulogic; -- system clock
                clk:          in  std_ulogic; -- system clock
                ps2_clk:      in  std_ulogic; -- clock signal from PS/2 keyboard
                ps2_clk:      in  std_ulogic; -- clock signal from PS/2 keyboard
                ps2_data:     in  std_ulogic; -- data signal from PS/2 keyboard
                ps2_data:     in  std_ulogic; -- data signal from PS/2 keyboard
                ps2_code_new: out std_ulogic; -- flag that new PS/2 code is available on ps2_code bus
                ps2_code_new: out std_ulogic; -- flag that new PS/2 code is available on ps2_code bus
                ps2_code:     out std_ulogic_vector(7 downto 0)); -- code received from PS/2
                ps2_code:     out std_ulogic_vector(7 downto 0)); -- code received from PS/2
        end component;
        end component;
 
 
        component ps2_debounce is
        component ps2_debounce is
                generic(counter_size:  integer := 19); --counter size (19 bits gives 10.5ms with 50mhz clock)
                generic(counter_size:  integer := 19); --counter size (19 bits gives 10.5ms with 50MHz clock)
                port(
                port(
                        clk:    in  std_ulogic;
                        clk:    in  std_ulogic;
                        button: in  std_ulogic;  --input signal to be debounced
                        button: in  std_ulogic;  --input signal to be debounced
                        result: out std_ulogic := '0'); --debounced signal
                        result: out std_ulogic := '0'); --debounced signal
        end component;
        end component;
 
 
        component keyboard is
        component keyboard is
                generic(
                generic(
                        clock_frequency:           integer := 50000000; -- system clock frequency in hz
                        g: common_generics;
                        ps2_debounce_counter_size: integer := 8);       -- set such that 2^size/clock_frequency = 5us (size = 8 for 50mhz)
                        ps2_debounce_counter_size: integer := 8);       -- set such that 2^size/clock_frequency = 5us (size = 8 for 50MHz)
                port(
                port(
                        clk:              in  std_ulogic;        -- system clock input
                        clk:              in  std_ulogic;        -- system clock input
                        rst:              in  std_ulogic;        -- system reset
                        rst:              in  std_ulogic;        -- system reset
 
 
                        ps2_clk:          in  std_ulogic;        -- clock signal from PS2 keyboard
                        ps2_clk:          in  std_ulogic;        -- clock signal from PS2 keyboard
                        ps2_data:         in  std_ulogic;        -- data signal from PS2 keyboard
                        ps2_data:         in  std_ulogic;        -- data signal from PS2 keyboard
 
 
                        kbd_char_re:      in  std_ulogic;        -- acknowledge kbd_char_buf_new
                        kbd_char_re:      in  std_ulogic;        -- acknowledge kbd_char_buf_new
                        kbd_char_buf_new: out std_ulogic := '0'; -- output flag indicating new ascii value
                        kbd_char_buf_new: out std_ulogic := '0'; -- output flag indicating new ascii value
                        kbd_char_buf:     out std_ulogic_vector(6 downto 0)); -- ASCII value
                        kbd_char_buf:     out std_ulogic_vector(6 downto 0)); -- ASCII value
        end component;
        end component;
end package;
end package;
 
 
------ Keyboard ----------------------------------------------------------------
------ Keyboard ----------------------------------------------------------------
library ieee;
library ieee, work;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use work.kbd_pkg.all;
use work.kbd_pkg.all;
 
use work.util.common_generics;
 
 
entity keyboard is
entity keyboard is
        generic(
        generic(
                clock_frequency:           integer := 50000000; -- system clock frequency in hz
                g: common_generics;
                ps2_debounce_counter_size: integer := 8);       -- set such that 2^size/clock_frequency = 5us (size = 8 for 50mhz)
                ps2_debounce_counter_size: integer := 8);       -- set such that 2^size/clock_frequency = 5us (size = 8 for 50MHz)
        port(
        port(
                clk:              in  std_ulogic;        -- system clock input
                clk:              in  std_ulogic;        -- system clock input
                rst:              in  std_ulogic;        -- system reset
                rst:              in  std_ulogic;        -- system reset
 
 
                ps2_clk:          in  std_ulogic;        -- clock signal from PS2 keyboard
                ps2_clk:          in  std_ulogic;        -- clock signal from PS2 keyboard
                ps2_data:         in  std_ulogic;        -- data signal from PS2 keyboard
                ps2_data:         in  std_ulogic;        -- data signal from PS2 keyboard
 
 
                kbd_char_re:      in  std_ulogic;        -- acknowledge kbd_char_buf_new
                kbd_char_re:      in  std_ulogic;        -- acknowledge kbd_char_buf_new
                kbd_char_buf_new: out std_ulogic := '0'; -- output flag indicating new ascii value
                kbd_char_buf_new: out std_ulogic := '0'; -- output flag indicating new ascii value
                kbd_char_buf:     out std_ulogic_vector(6 downto 0)); -- ASCII value
                kbd_char_buf:     out std_ulogic_vector(6 downto 0)); -- ASCII value
end entity;
end entity;
 
 
architecture rtl of keyboard  is
architecture rtl of keyboard  is
        signal kbd_new_c, kbd_new_n:  std_ulogic := '0';
        signal kbd_new_c, kbd_new_n:  std_ulogic := '0';
        signal kbd_new_edge: std_ulogic := '0';
        signal kbd_new_edge: std_ulogic := '0';
        signal kbd_new:      std_ulogic := '0';                                -- new ASCII char available
        signal kbd_new:      std_ulogic := '0'; -- new ASCII char available
        signal kbd_char:     std_ulogic_vector(kbd_char_buf'range) := (others => '0'); -- ASCII char
        signal kbd_char:     std_ulogic_vector(kbd_char_buf'range) := (others => '0'); -- ASCII char
        signal kbd_char_o:   std_ulogic_vector(kbd_char_buf'range) := (others => '0'); -- ASCII char
 
begin
begin
        kbd_char_buf_new <= kbd_new_c;
        kbd_char_buf_new <= kbd_new_c after g.delay;
 
 
        ps2_next: process(clk, rst)
        ps2_next: process(clk, rst)
        begin
        begin
                if rst = '1' then
                if rst = '1' and g.asynchronous_reset then
                        kbd_new_c  <= '0';
                        kbd_new_c  <= '0' after g.delay;
                elsif rising_edge(clk) then
                elsif rising_edge(clk) then
                        kbd_new_c   <= kbd_new_n;
                        if rst = '1' and not g.asynchronous_reset then
 
                                kbd_new_c <= '0' after g.delay;
 
                        else
 
                                kbd_new_c   <= kbd_new_n after g.delay;
 
                        end if;
                end if;
                end if;
        end process;
        end process;
 
 
        new_char: entity work.reg
        new_char: entity work.reg
        generic map(N => kbd_char'high+1)
        generic map(g => g, N => kbd_char'length)
        port map(
        port map(
                clk => clk,
                clk => clk,
                rst => rst,
                rst => rst,
                di  => kbd_char,
                di  => kbd_char,
                we  => kbd_new_edge,
                we  => kbd_new_edge,
                do  => kbd_char_o);
 
 
 
        char_buf: entity work.reg
 
        generic map(N => kbd_char'high+1)
 
        port map(
 
                clk => clk,
 
                rst => rst,
 
                di  => kbd_char_o,
 
                we  => kbd_char_re,
 
                do  => kbd_char_buf);
                do  => kbd_char_buf);
 
 
        ps2_proc: process(kbd_new_edge, kbd_new_c, kbd_char_re)
        ps2_proc: process(kbd_new_edge, kbd_new_c, kbd_char_re)
        begin
        begin
                if kbd_new_edge = '1' then
                if kbd_new_edge = '1' then
                        kbd_new_n  <= '1';
                        kbd_new_n  <= '1' after g.delay;
                elsif kbd_char_re = '1' then
                elsif kbd_char_re = '1' then
                        kbd_new_n  <= '0';
                        kbd_new_n  <= '0' after g.delay;
                else
                else
                        kbd_new_n  <= kbd_new_c;
                        kbd_new_n  <= kbd_new_c after g.delay;
                end if;
                end if;
        end process;
        end process;
 
 
        -- Process a kbd_new into a single edge for the rest of the
        -- Process a kbd_new into a single edge for the rest of the
        -- system.
        -- system.
        ps2_edge_new_character_0: entity work.rising_edge_detector
        ps2_edge_new_character_0: entity work.rising_edge_detector
 
        generic map(g => g)
        port map(
        port map(
                clk => clk,
                clk => clk,
                rst => rst,
                rst => rst,
                di  => kbd_new,
                di  => kbd_new,
                do  => kbd_new_edge);
                do  => kbd_new_edge);
 
 
        ps2_0: work.kbd_pkg.ps2_kbd_top
        ps2_0: work.kbd_pkg.ps2_kbd_top
        generic map(
        generic map(
                clock_frequency => clock_frequency,
                clock_frequency => g.clock_frequency,
                ps2_debounce_counter_size => ps2_debounce_counter_size)
                ps2_debounce_counter_size => ps2_debounce_counter_size)
        port map(
        port map(
                clk        => clk,
                clk        => clk,
                ps2_clk    => ps2_clk,
                ps2_clk    => ps2_clk,
                ps2_data   => ps2_data,
                ps2_data   => ps2_data,
                ascii_new  => kbd_new,
                ascii_new  => kbd_new,
                ascii_code => kbd_char);
                ascii_code => kbd_char);
end architecture;
end architecture;
------ Keyboard ----------------------------------------------------------------
------ Keyboard ----------------------------------------------------------------
 
 
------ PS2 KBD TOP -------------------------------------------------------------
------ PS2 KBD TOP -------------------------------------------------------------
 
 
library ieee;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use work.kbd_pkg.all;
use work.kbd_pkg.all;
 
 
entity ps2_kbd_top is
entity ps2_kbd_top is
        generic(
        generic(
                clock_frequency:           integer := 50000000; -- system clock frequency in hz
                clock_frequency:           integer := 50000000; -- system clock frequency in Hz
                ps2_debounce_counter_size: integer := 8);       -- set such that 2^size/clock_frequency = 5us (size = 8 for 50mhz)
                ps2_debounce_counter_size: integer := 8);       -- set such that 2^size/clock_frequency = 5us (size = 8 for 50MHz)
        port(
        port(
                clk:        in  std_ulogic;                     -- system clock input
                clk:        in  std_ulogic;                     -- system clock input
                ps2_clk:    in  std_ulogic;                     -- clock signal from PS2 keyboard
                ps2_clk:    in  std_ulogic;                     -- clock signal from PS2 keyboard
                ps2_data:   in  std_ulogic;                     -- data signal from PS2 keyboard
                ps2_data:   in  std_ulogic;                     -- data signal from PS2 keyboard
                ascii_new:  out std_ulogic := '0';              -- output flag indicating new ascii value
                ascii_new:  out std_ulogic := '0';              -- output flag indicating new ascii value
                ascii_code: out std_ulogic_vector(6 downto 0)); -- ASCII value
                ascii_code: out std_ulogic_vector(6 downto 0)); -- ASCII value
end entity;
end entity;
 
 
architecture rtl of ps2_kbd_top is
architecture rtl of ps2_kbd_top is
        type machine is(ready, new_code, translate, output); -- needed states
        type machine is(ready, new_code, translate, output); -- needed states
        signal state: machine;                               -- state machine
        signal state: machine;                               -- state machine
        signal ps2_code_new: std_ulogic;                      -- new PS2 code flag from ps2_kbd_core component
        signal ps2_code_new: std_ulogic;                      -- new PS2 code flag from ps2_kbd_core component
        signal ps2_code:     std_ulogic_vector(7 downto 0);   -- PS2 code input form ps2_kbd_core component
        signal ps2_code:     std_ulogic_vector(7 downto 0);   -- PS2 code input form ps2_kbd_core component
        signal prev_ps2_code_new: std_ulogic := '1';          -- value of ps2_code_new flag on previous clock
        signal prev_ps2_code_new: std_ulogic := '1';          -- value of ps2_code_new flag on previous clock
        signal break:        std_ulogic := '0';               -- '1' for break code, '0' for make code
        signal break:        std_ulogic := '0';               -- '1' for break code, '0' for make code
        signal e0_code:      std_ulogic := '0';               -- '1' for multi-code commands, '0' for single code commands
        signal e0_code:      std_ulogic := '0';               -- '1' for multi-code commands, '0' for single code commands
        signal caps_lock:    std_ulogic := '0';               -- '1' if caps lock is active, '0' if caps lock is inactive
        signal caps_lock:    std_ulogic := '0';               -- '1' if caps lock is active, '0' if caps lock is inactive
        signal control_r:    std_ulogic := '0';               -- '1' if right control key is held down, else '0'
        signal control_r:    std_ulogic := '0';               -- '1' if right control key is held down, else '0'
        signal control_l:    std_ulogic := '0';               -- '1' if left control key is held down, else '0'
        signal control_l:    std_ulogic := '0';               -- '1' if left control key is held down, else '0'
        signal shift_r:      std_ulogic := '0';               -- '1' if right shift is held down, else '0'
        signal shift_r:      std_ulogic := '0';               -- '1' if right shift is held down, else '0'
        signal shift_l:      std_ulogic := '0';               -- '1' if left shift is held down, else '0'
        signal shift_l:      std_ulogic := '0';               -- '1' if left shift is held down, else '0'
        signal ascii:        std_ulogic_vector(7 downto 0) := x"FF"; -- internal value of ASCII translation
        signal ascii:        std_ulogic_vector(7 downto 0) := x"FF"; -- internal value of ASCII translation
 
 
begin
begin
 
 
        -- instantiate PS2 keyboard interface logic
        -- instantiate PS2 keyboard interface logic
        ps2_kbd_core_0: work.kbd_pkg.ps2_kbd_core
        ps2_kbd_core_0: work.kbd_pkg.ps2_kbd_core
                generic map(
                generic map(
                        clock_frequency       => clock_frequency,
                        clock_frequency       => clock_frequency,
                        debounce_counter_size => ps2_debounce_counter_size)
                        debounce_counter_size => ps2_debounce_counter_size)
                port map(
                port map(
                        clk                   => clk,
                        clk                   => clk,
                        ps2_clk               => ps2_clk,
                        ps2_clk               => ps2_clk,
                        ps2_data              => ps2_data,
                        ps2_data              => ps2_data,
                        ps2_code_new          => ps2_code_new,
                        ps2_code_new          => ps2_code_new,
                        ps2_code              => ps2_code);
                        ps2_code              => ps2_code);
 
 
        process(clk)
        process(clk)
        begin
        begin
        if rising_edge(clk) then
        if rising_edge(clk) then
                prev_ps2_code_new <= ps2_code_new; -- keep track of previous ps2_code_new values to determine low-to-high transitions
                prev_ps2_code_new <= ps2_code_new; -- keep track of previous ps2_code_new values to determine low-to-high transitions
                case state is
                case state is
 
 
                        -- ready state: wait for a new PS2 code to be received
                        -- ready state: wait for a new PS2 code to be received
                        when ready =>
                        when ready =>
                                if(prev_ps2_code_new = '0' AND ps2_code_new = '1') then -- new PS2 code received
                                if(prev_ps2_code_new = '0' AND ps2_code_new = '1') then -- new PS2 code received
                                        ascii_new <= '0';                               -- reset new ASCII code indicator
                                        ascii_new <= '0';                               -- reset new ASCII code indicator
                                        state <= new_code;                              -- proceed to new_code state
                                        state <= new_code;                              -- proceed to new_code state
                                else                                                    -- no new PS2 code received yet
                                else                                                    -- no new PS2 code received yet
                                        state <= ready;                                 -- remain in ready state
                                        state <= ready;                                 -- remain in ready state
                                end if;
                                end if;
 
 
                        -- new_code state: determine what to do with the new PS2 code
                        -- new_code state: determine what to do with the new PS2 code
                        when new_code =>
                        when new_code =>
                                if(ps2_code = x"F0") then    -- code indicates that next command is break
                                if(ps2_code = x"F0") then    -- code indicates that next command is break
                                        break <= '1';        -- set break flag
                                        break <= '1';        -- set break flag
                                        state <= ready;      -- return to ready state to await next PS2 code
                                        state <= ready;      -- return to ready state to await next PS2 code
                                elsif(ps2_code = x"E0") then -- code indicates multi-key command
                                elsif(ps2_code = x"E0") then -- code indicates multi-key command
                                        e0_code <= '1';      -- set multi-code command flag
                                        e0_code <= '1';      -- set multi-code command flag
                                        state <= ready;      -- return to ready state to await next PS2 code
                                        state <= ready;      -- return to ready state to await next PS2 code
                                else                         -- code is the last PS2 code in the make/break code
                                else                         -- code is the last PS2 code in the make/break code
                                        ascii(7) <= '1';     -- set internal ascii value to unsupported code (for verification)
                                        ascii(7) <= '1';     -- set internal ascii value to unsupported code (for verification)
                                        state <= translate;  -- proceed to translate state
                                        state <= translate;  -- proceed to translate state
                                end if;
                                end if;
 
 
                        -- translate state: translate PS2 code to ASCII value
                        -- translate state: translate PS2 code to ASCII value
                        when translate =>
                        when translate =>
                                        break <= '0';    -- reset break flag
                                        break <= '0';    -- reset break flag
                                        e0_code <= '0';  -- reset multi-code command flag
                                        e0_code <= '0';  -- reset multi-code command flag
 
 
                                        -- handle codes for control, shift, and caps lock
                                        -- handle codes for control, shift, and caps lock
                                        case ps2_code is
                                        case ps2_code is
                                                when x"58" =>                   -- caps lock code
                                                when x"58" =>                   -- caps lock code
                                                        if(break = '0') then    -- if make command
                                                        if(break = '0') then    -- if make command
                                                                caps_lock <= NOT caps_lock; -- toggle caps lock
                                                                caps_lock <= NOT caps_lock; -- toggle caps lock
                                                        end if;
                                                        end if;
                                                when x"14" =>                   -- code for the control keys
                                                when x"14" =>                   -- code for the control keys
                                                        if(e0_code = '1') then          -- code for right control
                                                        if(e0_code = '1') then          -- code for right control
                                                                control_r <= NOT break; -- update right control flag
                                                                control_r <= NOT break; -- update right control flag
                                                        else                            -- code for left control
                                                        else                            -- code for left control
                                                                control_l <= NOT break; -- update left control flag
                                                                control_l <= NOT break; -- update left control flag
                                                        end if;
                                                        end if;
                                                when x"12" =>                   -- left shift code
                                                when x"12" =>                   -- left shift code
                                                        shift_l <= NOT break;   -- update left shift flag
                                                        shift_l <= NOT break;   -- update left shift flag
                                                when x"59" =>                   -- right shift code
                                                when x"59" =>                   -- right shift code
                                                        shift_r <= NOT break;   -- update right shift flag
                                                        shift_r <= NOT break;   -- update right shift flag
                                                when others => null;
                                                when others => null;
                                        end case;
                                        end case;
 
 
                                        -- translate control codes (these do not depend on shift or caps lock)
                                        -- translate control codes (these do not depend on shift or caps lock)
                                        if(control_l = '1' OR control_r = '1') then
                                        if(control_l = '1' OR control_r = '1') then
                                                case ps2_code is
                                                case ps2_code is
                                                        when x"1E" => ascii <= x"00"; -- ^@  NUL
                                                        when x"1E" => ascii <= x"00"; -- ^@  NUL
                                                        when x"1C" => ascii <= x"01"; -- ^A  SOH
                                                        when x"1C" => ascii <= x"01"; -- ^A  SOH
                                                        when x"32" => ascii <= x"02"; -- ^B  STX
                                                        when x"32" => ascii <= x"02"; -- ^B  STX
                                                        when x"21" => ascii <= x"03"; -- ^C  ETX
                                                        when x"21" => ascii <= x"03"; -- ^C  ETX
                                                        when x"23" => ascii <= x"04"; -- ^D  EOT
                                                        when x"23" => ascii <= x"04"; -- ^D  EOT
                                                        when x"24" => ascii <= x"05"; -- ^E  ENQ
                                                        when x"24" => ascii <= x"05"; -- ^E  ENQ
                                                        when x"2B" => ascii <= x"06"; -- ^F  ACK
                                                        when x"2B" => ascii <= x"06"; -- ^F  ACK
                                                        when x"34" => ascii <= x"07"; -- ^G  BEL
                                                        when x"34" => ascii <= x"07"; -- ^G  BEL
                                                        when x"33" => ascii <= x"08"; -- ^H  BS
                                                        when x"33" => ascii <= x"08"; -- ^H  BS
                                                        when x"43" => ascii <= x"09"; -- ^I  HT
                                                        when x"43" => ascii <= x"09"; -- ^I  HT
                                                        when x"3B" => ascii <= x"0A"; -- ^J  LF
                                                        when x"3B" => ascii <= x"0A"; -- ^J  LF
                                                        when x"42" => ascii <= x"0B"; -- ^K  VT
                                                        when x"42" => ascii <= x"0B"; -- ^K  VT
                                                        when x"4B" => ascii <= x"0C"; -- ^L  FF
                                                        when x"4B" => ascii <= x"0C"; -- ^L  FF
                                                        when x"3A" => ascii <= x"0D"; -- ^M  CR
                                                        when x"3A" => ascii <= x"0D"; -- ^M  CR
                                                        when x"31" => ascii <= x"0E"; -- ^N  SO
                                                        when x"31" => ascii <= x"0E"; -- ^N  SO
                                                        when x"44" => ascii <= x"0F"; -- ^O  SI
                                                        when x"44" => ascii <= x"0F"; -- ^O  SI
                                                        when x"4D" => ascii <= x"10"; -- ^P  DLE
                                                        when x"4D" => ascii <= x"10"; -- ^P  DLE
                                                        when x"15" => ascii <= x"11"; -- ^Q  DC1
                                                        when x"15" => ascii <= x"11"; -- ^Q  DC1
                                                        when x"2D" => ascii <= x"12"; -- ^R  DC2
                                                        when x"2D" => ascii <= x"12"; -- ^R  DC2
                                                        when x"1B" => ascii <= x"13"; -- ^S  DC3
                                                        when x"1B" => ascii <= x"13"; -- ^S  DC3
                                                        when x"2C" => ascii <= x"14"; -- ^T  DC4
                                                        when x"2C" => ascii <= x"14"; -- ^T  DC4
                                                        when x"3C" => ascii <= x"15"; -- ^U  NAK
                                                        when x"3C" => ascii <= x"15"; -- ^U  NAK
                                                        when x"2A" => ascii <= x"16"; -- ^V  SYN
                                                        when x"2A" => ascii <= x"16"; -- ^V  SYN
                                                        when x"1D" => ascii <= x"17"; -- ^W  ETB
                                                        when x"1D" => ascii <= x"17"; -- ^W  ETB
                                                        when x"22" => ascii <= x"18"; -- ^X  CAN
                                                        when x"22" => ascii <= x"18"; -- ^X  CAN
                                                        when x"35" => ascii <= x"19"; -- ^Y  EM
                                                        when x"35" => ascii <= x"19"; -- ^Y  EM
                                                        when x"1A" => ascii <= x"1A"; -- ^Z  SUB
                                                        when x"1A" => ascii <= x"1A"; -- ^Z  SUB
                                                        when x"54" => ascii <= x"1B"; -- ^[  ESC
                                                        when x"54" => ascii <= x"1B"; -- ^[  ESC
                                                        when x"5D" => ascii <= x"1C"; -- ^\  FS
                                                        when x"5D" => ascii <= x"1C"; -- ^\  FS
                                                        when x"5B" => ascii <= x"1D"; -- ^]  GS
                                                        when x"5B" => ascii <= x"1D"; -- ^]  GS
                                                        when x"36" => ascii <= x"1E"; -- ^^  RS
                                                        when x"36" => ascii <= x"1E"; -- ^^  RS
                                                        when x"4E" => ascii <= x"1F"; -- ^_  US
                                                        when x"4E" => ascii <= x"1F"; -- ^_  US
                                                        when x"4A" => ascii <= x"7F"; -- ^?  DEL
                                                        when x"4A" => ascii <= x"7F"; -- ^?  DEL
                                                        when others => null;
                                                        when others => null;
                                                end case;
                                                end case;
                                        else -- if control keys are not pressed
                                        else -- if control keys are not pressed
 
 
                                                -- translate characters that do not depend on shift, or caps lock
                                                -- translate characters that do not depend on shift, or caps lock
                                                case ps2_code is
                                                case ps2_code is
                                                        when x"29" => ascii <= x"20"; -- space
                                                        when x"29" => ascii <= x"20"; -- space
                                                        when x"66" => ascii <= x"08"; -- backspace (BS control code)
                                                        when x"66" => ascii <= x"08"; -- backspace (BS control code)
                                                        when x"0D" => ascii <= x"09"; -- tab (HT control code)
                                                        when x"0D" => ascii <= x"09"; -- tab (HT control code)
                                                        when x"5A" => ascii <= x"0D"; -- enter (CR control code)
                                                        when x"5A" => ascii <= x"0D"; -- enter (CR control code)
                                                        when x"76" => ascii <= x"1B"; -- escape (ESC control code)
                                                        when x"76" => ascii <= x"1B"; -- escape (ESC control code)
                                                        when x"71" =>
                                                        when x"71" =>
                                                                if(e0_code = '1') then  -- ps2 code for delete is a multi-key code
                                                                if(e0_code = '1') then  -- ps2 code for delete is a multi-key code
                                                                        ascii <= x"7F"; -- delete
                                                                        ascii <= x"7F"; -- delete
                                                                end if;
                                                                end if;
                                                        when others => null;
                                                        when others => null;
                                                end case;
                                                end case;
 
 
                                                -- translate letters (these depend on both shift and caps lock)
                                                -- translate letters (these depend on both shift and caps lock)
                                                if((shift_r = '0' AND shift_l = '0' AND caps_lock = '0') OR
                                                if((shift_r = '0' AND shift_l = '0' AND caps_lock = '0') OR
                                                        ((shift_r = '1' OR shift_l = '1') AND caps_lock = '1')) then  -- letter is lowercase
                                                        ((shift_r = '1' OR shift_l = '1') AND caps_lock = '1')) then  -- letter is lowercase
                                                        case ps2_code is
                                                        case ps2_code is
                                                                when x"1C" => ascii <= x"61"; -- a
                                                                when x"1C" => ascii <= x"61"; -- a
                                                                when x"32" => ascii <= x"62"; -- b
                                                                when x"32" => ascii <= x"62"; -- b
                                                                when x"21" => ascii <= x"63"; -- c
                                                                when x"21" => ascii <= x"63"; -- c
                                                                when x"23" => ascii <= x"64"; -- d
                                                                when x"23" => ascii <= x"64"; -- d
                                                                when x"24" => ascii <= x"65"; -- e
                                                                when x"24" => ascii <= x"65"; -- e
                                                                when x"2B" => ascii <= x"66"; -- f
                                                                when x"2B" => ascii <= x"66"; -- f
                                                                when x"34" => ascii <= x"67"; -- g
                                                                when x"34" => ascii <= x"67"; -- g
                                                                when x"33" => ascii <= x"68"; -- h
                                                                when x"33" => ascii <= x"68"; -- h
                                                                when x"43" => ascii <= x"69"; -- i
                                                                when x"43" => ascii <= x"69"; -- i
                                                                when x"3B" => ascii <= x"6A"; -- j
                                                                when x"3B" => ascii <= x"6A"; -- j
                                                                when x"42" => ascii <= x"6B"; -- k
                                                                when x"42" => ascii <= x"6B"; -- k
                                                                when x"4B" => ascii <= x"6C"; -- l
                                                                when x"4B" => ascii <= x"6C"; -- l
                                                                when x"3A" => ascii <= x"6D"; -- m
                                                                when x"3A" => ascii <= x"6D"; -- m
                                                                when x"31" => ascii <= x"6E"; -- n
                                                                when x"31" => ascii <= x"6E"; -- n
                                                                when x"44" => ascii <= x"6F"; -- o
                                                                when x"44" => ascii <= x"6F"; -- o
                                                                when x"4D" => ascii <= x"70"; -- p
                                                                when x"4D" => ascii <= x"70"; -- p
                                                                when x"15" => ascii <= x"71"; -- q
                                                                when x"15" => ascii <= x"71"; -- q
                                                                when x"2D" => ascii <= x"72"; -- r
                                                                when x"2D" => ascii <= x"72"; -- r
                                                                when x"1B" => ascii <= x"73"; -- s
                                                                when x"1B" => ascii <= x"73"; -- s
                                                                when x"2C" => ascii <= x"74"; -- t
                                                                when x"2C" => ascii <= x"74"; -- t
                                                                when x"3C" => ascii <= x"75"; -- u
                                                                when x"3C" => ascii <= x"75"; -- u
                                                                when x"2A" => ascii <= x"76"; -- v
                                                                when x"2A" => ascii <= x"76"; -- v
                                                                when x"1D" => ascii <= x"77"; -- w
                                                                when x"1D" => ascii <= x"77"; -- w
                                                                when x"22" => ascii <= x"78"; -- x
                                                                when x"22" => ascii <= x"78"; -- x
                                                                when x"35" => ascii <= x"79"; -- y
                                                                when x"35" => ascii <= x"79"; -- y
                                                                when x"1A" => ascii <= x"7A"; -- z
                                                                when x"1A" => ascii <= x"7A"; -- z
                                                                when others => null;
                                                                when others => null;
                                                        end case;
                                                        end case;
                                                else                                     -- letter is uppercase
                                                else                                     -- letter is uppercase
                                                        case ps2_code is
                                                        case ps2_code is
                                                                when x"1C" => ascii <= x"41"; -- A
                                                                when x"1C" => ascii <= x"41"; -- A
                                                                when x"32" => ascii <= x"42"; -- B
                                                                when x"32" => ascii <= x"42"; -- B
                                                                when x"21" => ascii <= x"43"; -- C
                                                                when x"21" => ascii <= x"43"; -- C
                                                                when x"23" => ascii <= x"44"; -- D
                                                                when x"23" => ascii <= x"44"; -- D
                                                                when x"24" => ascii <= x"45"; -- E
                                                                when x"24" => ascii <= x"45"; -- E
                                                                when x"2B" => ascii <= x"46"; -- F
                                                                when x"2B" => ascii <= x"46"; -- F
                                                                when x"34" => ascii <= x"47"; -- G
                                                                when x"34" => ascii <= x"47"; -- G
                                                                when x"33" => ascii <= x"48"; -- H
                                                                when x"33" => ascii <= x"48"; -- H
                                                                when x"43" => ascii <= x"49"; -- I
                                                                when x"43" => ascii <= x"49"; -- I
                                                                when x"3B" => ascii <= x"4A"; -- J
                                                                when x"3B" => ascii <= x"4A"; -- J
                                                                when x"42" => ascii <= x"4B"; -- K
                                                                when x"42" => ascii <= x"4B"; -- K
                                                                when x"4B" => ascii <= x"4C"; -- L
                                                                when x"4B" => ascii <= x"4C"; -- L
                                                                when x"3A" => ascii <= x"4D"; -- M
                                                                when x"3A" => ascii <= x"4D"; -- M
                                                                when x"31" => ascii <= x"4E"; -- N
                                                                when x"31" => ascii <= x"4E"; -- N
                                                                when x"44" => ascii <= x"4F"; -- O
                                                                when x"44" => ascii <= x"4F"; -- O
                                                                when x"4D" => ascii <= x"50"; -- P
                                                                when x"4D" => ascii <= x"50"; -- P
                                                                when x"15" => ascii <= x"51"; -- Q
                                                                when x"15" => ascii <= x"51"; -- Q
                                                                when x"2D" => ascii <= x"52"; -- R
                                                                when x"2D" => ascii <= x"52"; -- R
                                                                when x"1B" => ascii <= x"53"; -- S
                                                                when x"1B" => ascii <= x"53"; -- S
                                                                when x"2C" => ascii <= x"54"; -- T
                                                                when x"2C" => ascii <= x"54"; -- T
                                                                when x"3C" => ascii <= x"55"; -- U
                                                                when x"3C" => ascii <= x"55"; -- U
                                                                when x"2A" => ascii <= x"56"; -- V
                                                                when x"2A" => ascii <= x"56"; -- V
                                                                when x"1D" => ascii <= x"57"; -- W
                                                                when x"1D" => ascii <= x"57"; -- W
                                                                when x"22" => ascii <= x"58"; -- X
                                                                when x"22" => ascii <= x"58"; -- X
                                                                when x"35" => ascii <= x"59"; -- Y
                                                                when x"35" => ascii <= x"59"; -- Y
                                                                when x"1A" => ascii <= x"5A"; -- Z
                                                                when x"1A" => ascii <= x"5A"; -- Z
                                                                when others => null;
                                                                when others => null;
                                                        end case;
                                                        end case;
                                                end if;
                                                end if;
 
 
                                                -- translate numbers and symbols (these depend on shift but not caps lock)
                                                -- translate numbers and symbols (these depend on shift but not caps lock)
                                                if(shift_l = '1' OR shift_r = '1') then  -- key's secondary character is desired
                                                if(shift_l = '1' OR shift_r = '1') then  -- key's secondary character is desired
                                                        case ps2_code is
                                                        case ps2_code is
                                                                when x"16" => ascii <= x"21"; -- |
                                                                when x"16" => ascii <= x"21"; -- |
                                                                when x"52" => ascii <= x"22"; -- "
                                                                when x"52" => ascii <= x"22"; -- "
                                                                when x"26" => ascii <= x"23"; -- #
                                                                when x"26" => ascii <= x"23"; -- #
                                                                when x"25" => ascii <= x"24"; -- $
                                                                when x"25" => ascii <= x"24"; -- $
                                                                when x"2E" => ascii <= x"25"; -- %
                                                                when x"2E" => ascii <= x"25"; -- %
                                                                when x"3D" => ascii <= x"26"; -- &
                                                                when x"3D" => ascii <= x"26"; -- &
                                                                when x"46" => ascii <= x"28"; -- (
                                                                when x"46" => ascii <= x"28"; -- (
                                                                when x"45" => ascii <= x"29"; -- )
                                                                when x"45" => ascii <= x"29"; -- )
                                                                when x"3E" => ascii <= x"2A"; -- *
                                                                when x"3E" => ascii <= x"2A"; -- *
                                                                when x"55" => ascii <= x"2B"; -- +
                                                                when x"55" => ascii <= x"2B"; -- +
                                                                when x"4C" => ascii <= x"3A"; -- :
                                                                when x"4C" => ascii <= x"3A"; -- :
                                                                when x"41" => ascii <= x"3C"; -- <
                                                                when x"41" => ascii <= x"3C"; -- <
                                                                when x"49" => ascii <= x"3E"; -- >
                                                                when x"49" => ascii <= x"3E"; -- >
                                                                when x"4A" => ascii <= x"3F"; -- ?
                                                                when x"4A" => ascii <= x"3F"; -- ?
                                                                when x"1E" => ascii <= x"40"; -- @
                                                                when x"1E" => ascii <= x"40"; -- @
                                                                when x"36" => ascii <= x"5E"; -- ^
                                                                when x"36" => ascii <= x"5E"; -- ^
                                                                when x"4E" => ascii <= x"5F"; -- _
                                                                when x"4E" => ascii <= x"5F"; -- _
                                                                when x"54" => ascii <= x"7B"; -- {
                                                                when x"54" => ascii <= x"7B"; -- {
                                                                when x"5D" => ascii <= x"7C"; -- |
                                                                when x"5D" => ascii <= x"7C"; -- |
                                                                when x"5B" => ascii <= x"7D"; -- }
                                                                when x"5B" => ascii <= x"7D"; -- }
                                                                when x"0E" => ascii <= x"7E"; -- ~
                                                                when x"0E" => ascii <= x"7E"; -- ~
                                                                when others => null;
                                                                when others => null;
                                                        end case;
                                                        end case;
                                                else -- key's primary character is desired
                                                else -- key's primary character is desired
                                                        case ps2_code is
                                                        case ps2_code is
                                                                when x"45" => ascii <= x"30"; -- 0
                                                                when x"45" => ascii <= x"30"; -- 0
                                                                when x"16" => ascii <= x"31"; -- 1
                                                                when x"16" => ascii <= x"31"; -- 1
                                                                when x"1E" => ascii <= x"32"; -- 2
                                                                when x"1E" => ascii <= x"32"; -- 2
                                                                when x"26" => ascii <= x"33"; -- 3
                                                                when x"26" => ascii <= x"33"; -- 3
                                                                when x"25" => ascii <= x"34"; -- 4
                                                                when x"25" => ascii <= x"34"; -- 4
                                                                when x"2E" => ascii <= x"35"; -- 5
                                                                when x"2E" => ascii <= x"35"; -- 5
                                                                when x"36" => ascii <= x"36"; -- 6
                                                                when x"36" => ascii <= x"36"; -- 6
                                                                when x"3D" => ascii <= x"37"; -- 7
                                                                when x"3D" => ascii <= x"37"; -- 7
                                                                when x"3E" => ascii <= x"38"; -- 8
                                                                when x"3E" => ascii <= x"38"; -- 8
                                                                when x"46" => ascii <= x"39"; -- 9
                                                                when x"46" => ascii <= x"39"; -- 9
                                                                when x"52" => ascii <= x"27"; -- '
                                                                when x"52" => ascii <= x"27"; -- '
                                                                when x"41" => ascii <= x"2C"; -- ,
                                                                when x"41" => ascii <= x"2C"; -- ,
                                                                when x"4E" => ascii <= x"2D"; -- -
                                                                when x"4E" => ascii <= x"2D"; -- -
                                                                when x"49" => ascii <= x"2E"; -- .
                                                                when x"49" => ascii <= x"2E"; -- .
                                                                when x"4A" => ascii <= x"2F"; -- /
                                                                when x"4A" => ascii <= x"2F"; -- /
                                                                when x"4C" => ascii <= x"3B"; -- ;
                                                                when x"4C" => ascii <= x"3B"; -- ;
                                                                when x"55" => ascii <= x"3D"; -- =
                                                                when x"55" => ascii <= x"3D"; -- =
                                                                when x"54" => ascii <= x"5B"; -- [
                                                                when x"54" => ascii <= x"5B"; -- [
                                                                when x"5D" => ascii <= x"5C"; -- \
                                                                when x"5D" => ascii <= x"5C"; -- \
                                                                when x"5B" => ascii <= x"5D"; -- ]
                                                                when x"5B" => ascii <= x"5D"; -- ]
                                                                when x"0E" => ascii <= x"60"; -- `
                                                                when x"0E" => ascii <= x"60"; -- `
                                                                when others => null;
                                                                when others => null;
                                                        end case;
                                                        end case;
                                                end if;
                                                end if;
 
 
                                        end if;
                                        end if;
 
 
                                if(break = '0') then  -- the code is a make
                                if(break = '0') then  -- the code is a make
                                        state <= output;      -- proceed to output state
                                        state <= output;      -- proceed to output state
                                else                  -- code is a break
                                else                  -- code is a break
                                        state <= ready;       -- return to ready state to await next PS2 code
                                        state <= ready;       -- return to ready state to await next PS2 code
                                end if;
                                end if;
 
 
                        -- output state: verify the code is valid and output the ASCII value
                        -- output state: verify the code is valid and output the ASCII value
                        when output =>
                        when output =>
                                if(ascii(7) = '0') then            -- the PS2 code has an ASCII output
                                if(ascii(7) = '0') then            -- the PS2 code has an ASCII output
                                        ascii_new <= '1';                  -- set flag indicating new ASCII output
                                        ascii_new <= '1';                  -- set flag indicating new ASCII output
                                        ascii_code <= ascii(6 downto 0);   -- output the ASCII value
                                        ascii_code <= ascii(6 downto 0);   -- output the ASCII value
                                end if;
                                end if;
                                state <= ready;                    -- return to ready state to await next PS2 code
                                state <= ready;                    -- return to ready state to await next PS2 code
 
 
                end case;
                end case;
        end if;
        end if;
        end process;
        end process;
 
 
end;
end;
 
 
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--
--
--   FileName:         ps2_kbd_core.vhd
--   FileName:         ps2_kbd_core.vhd
--   Dependencies:     debounce.vhd
--   Dependencies:     debounce.vhd
--   Design Software:  Quartus II 32-bit Version 12.1 Build 177 SJ Full Version
--   Design Software:  Quartus II 32-bit Version 12.1 Build 177 SJ Full Version
--
--
--   HDL CODE IS PROVIDED "AS IS."  DIGI-KEY EXPRESSLY DISCLAIMS ANY
--   HDL CODE IS PROVIDED "AS IS."  DIGI-KEY EXPRESSLY DISCLAIMS ANY
--   WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
--   WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
--   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
--   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
--   PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
--   PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
--   BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
--   BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
--   DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
--   DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
--   PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
--   PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
--   BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
--   BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
--   ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
--   ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
--
--
--   Version History
--   Version History
--   Version 1.0 11/25/2013 Scott Larson
--   Version 1.0 11/25/2013 Scott Larson
--     Initial Public Release
--     Initial Public Release
--
--
--   @note This file has been modified from the original one found at
--   @note This file has been modified from the original one found at
--   <https://eewiki.net/pages/viewpage.action?pageId=28279002>
--   <https://eewiki.net/pages/viewpage.action?pageId=28279002>
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
 
 
library ieee;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
 
 
entity ps2_kbd_core is
entity ps2_kbd_core is
        generic(
        generic(
                clock_frequency: integer := 50000000;  -- system clock frequency in hz
                clock_frequency: integer := 50000000;  -- system clock frequency in Hz
                debounce_counter_size: integer := 8);  -- set such that (2^size)/clock_frequency = 5us (size = 8 for 50mhz)
                debounce_counter_size: integer := 8);  -- set such that (2^size)/clock_frequency = 5us (size = 8 for 50MHz)
        port(
        port(
                clk:          in  std_ulogic; -- system clock
                clk:          in  std_ulogic; -- system clock
                ps2_clk:      in  std_ulogic; -- clock signal from PS/2 keyboard
                ps2_clk:      in  std_ulogic; -- clock signal from PS/2 keyboard
                ps2_data:     in  std_ulogic; -- data signal from PS/2 keyboard
                ps2_data:     in  std_ulogic; -- data signal from PS/2 keyboard
                ps2_code_new: out std_ulogic; -- flag that new PS/2 code is available on ps2_code bus
                ps2_code_new: out std_ulogic; -- flag that new PS/2 code is available on ps2_code bus
                ps2_code:     out std_ulogic_vector(7 downto 0)); -- code received from PS/2
                ps2_code:     out std_ulogic_vector(7 downto 0)); -- code received from PS/2
end entity;
end entity;
 
 
architecture rtl of ps2_kbd_core is
architecture rtl of ps2_kbd_core is
 
 
        signal sync_ffs: std_ulogic_vector(1 downto 0);        -- synchronizer flip-flops for PS/2 signals
        signal sync_ffs: std_ulogic_vector(1 downto 0);        -- synchronizer flip-flops for PS/2 signals
        signal ps2_clk_int: std_ulogic;                        -- debounced clock signal from PS/2 keyboard
        signal ps2_clk_int: std_ulogic;                        -- debounced clock signal from PS/2 keyboard
 
 
        attribute buffer_type: string;
        attribute buffer_type: string;
        attribute buffer_type of ps2_clk_int: signal is "BUFG";
        attribute buffer_type of ps2_clk_int: signal is "BUFG";
 
 
        signal ps2_data_int: std_ulogic;                       -- debounced data signal from PS/2 keyboard
        signal ps2_data_int: std_ulogic;                       -- debounced data signal from PS/2 keyboard
        signal ps2_word: std_ulogic_vector(10 downto 0);       -- stores the ps2 data word
        signal ps2_word: std_ulogic_vector(10 downto 0);       -- stores the ps2 data word
        signal parity_error: std_ulogic;                       -- validate parity, start, and stop bits
        signal parity_error: std_ulogic;                       -- validate parity, start, and stop bits
        signal count_idle: integer range 0 to clock_frequency/18000; --counter to determine PS/2 is idle
        signal count_idle: integer range 0 to clock_frequency/18000; --counter to determine PS/2 is idle
 
 
begin
begin
 
 
        --synchronizer flip-flops
        --synchronizer flip-flops
        process(clk)
        process(clk)
        begin
        begin
                if rising_edge(clk) then         -- rising edge of system clock
                if rising_edge(clk) then         -- rising edge of system clock
                        sync_ffs(0) <= ps2_clk;  -- synchronize PS/2 clock signal
                        sync_ffs(0) <= ps2_clk;  -- synchronize PS/2 clock signal
                        sync_ffs(1) <= ps2_data; -- synchronize PS/2 data signal
                        sync_ffs(1) <= ps2_data; -- synchronize PS/2 data signal
                end if;
                end if;
        end process;
        end process;
 
 
        -- debounce ps2 input signals
        -- debounce ps2 input signals
        debounce_ps2_clk: work.kbd_pkg.ps2_debounce
        debounce_ps2_clk: work.kbd_pkg.ps2_debounce
        generic map(counter_size => debounce_counter_size)
        generic map(counter_size => debounce_counter_size)
        port map(clk => clk, button => sync_ffs(0), result => ps2_clk_int);
        port map(clk => clk, button => sync_ffs(0), result => ps2_clk_int);
 
 
        debounce_ps2_data: work.kbd_pkg.ps2_debounce
        debounce_ps2_data: work.kbd_pkg.ps2_debounce
        generic map(counter_size => debounce_counter_size)
        generic map(counter_size => debounce_counter_size)
        port map(clk => clk, button => sync_ffs(1), result => ps2_data_int);
        port map(clk => clk, button => sync_ffs(1), result => ps2_data_int);
 
 
        -- input ps2 data
        -- input ps2 data
        process(ps2_clk_int)
        process(ps2_clk_int)
        begin
        begin
                if(ps2_clk_int'event and ps2_clk_int = '0') then          -- falling edge of ps2 clock
                if(ps2_clk_int'event and ps2_clk_int = '0') then          -- falling edge of ps2 clock
                        ps2_word <= ps2_data_int & ps2_word(10 downto 1); -- shift in ps2 data bit
                        ps2_word <= ps2_data_int & ps2_word(10 downto 1); -- shift in ps2 data bit
                end if;
                end if;
        end process;
        end process;
 
 
        -- verify that parity, start, and stop bits are all correct
        -- verify that parity, start, and stop bits are all correct
        parity_error <= not (not ps2_word(0) and ps2_word(10) and (ps2_word(9) xor ps2_word(8) xor
        parity_error <= not (not ps2_word(0) and ps2_word(10) and (ps2_word(9) xor ps2_word(8) xor
            ps2_word(7) xor ps2_word(6) xor ps2_word(5) xor ps2_word(4) xor ps2_word(3) xor
            ps2_word(7) xor ps2_word(6) xor ps2_word(5) xor ps2_word(4) xor ps2_word(3) xor
            ps2_word(2) xor ps2_word(1)));
            ps2_word(2) xor ps2_word(1)));
 
 
        -- determine if ps2 port is idle (i.e. last transaction is finished) and output result
        -- determine if ps2 port is idle (i.e. last transaction is finished) and output result
        process(clk)
        process(clk)
        begin
        begin
                if rising_edge(clk) then                           -- rising edge of system clock
                if rising_edge(clk) then                           -- rising edge of system clock
                        if(ps2_clk_int = '0') then                 -- low ps2 clock, PS/2 is active
                        if(ps2_clk_int = '0') then                 -- low ps2 clock, PS/2 is active
                                count_idle <= 0;                   -- reset idle counter
                                count_idle <= 0;                   -- reset idle counter
                        elsif(count_idle /= clock_frequency/18_000) then  -- ps2 clock has been high less than a half clock period (<55us)
                        elsif(count_idle /= clock_frequency/18_000) then  -- ps2 clock has been high less than a half clock period (<55us)
                                count_idle <= count_idle + 1;      -- continue counting
                                count_idle <= count_idle + 1;      -- continue counting
                        end if;
                        end if;
 
 
                        if(count_idle = clock_frequency/18_000 and parity_error = '0') then  -- idle threshold reached and no errors detected
                        if(count_idle = clock_frequency/18_000 and parity_error = '0') then  -- idle threshold reached and no errors detected
                                ps2_code_new <= '1';                           -- set flag that new PS/2 code is available
                                ps2_code_new <= '1';                           -- set flag that new PS/2 code is available
                                ps2_code <= ps2_word(8 downto 1);              -- output new PS/2 code
                                ps2_code <= ps2_word(8 downto 1);              -- output new PS/2 code
                        else                                                   -- PS/2 port active or error detected
                        else                                                   -- PS/2 port active or error detected
                                ps2_code_new <= '0';                           -- set flag that PS/2 transaction is in progress
                                ps2_code_new <= '0';                           -- set flag that PS/2 transaction is in progress
                        end if;
                        end if;
                end if;
                end if;
        end process;
        end process;
 
 
end;
end;
 
 
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--
--
--   FileName:         (originally) debounce.vhd
--   FileName:         (originally) debounce.vhd
--   Dependencies:     none
--   Dependencies:     none
--   Design Software:  Quartus II 32-bit Version 11.1 Build 173 SJ Full Version
--   Design Software:  Quartus II 32-bit Version 11.1 Build 173 SJ Full Version
--
--
--   HDL CODE IS PROVIDED "AS IS."  DIGI-KEY EXPRESSLY DISCLAIMS ANY
--   HDL CODE IS PROVIDED "AS IS."  DIGI-KEY EXPRESSLY DISCLAIMS ANY
--   WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
--   WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
--   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
--   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
--   PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
--   PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
--   BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
--   BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
--   DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
--   DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
--   PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
--   PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
--   BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
--   BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
--   ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
--   ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
--
--
--   Version History
--   Version History
--   Version 1.0 3/26/2012 Scott Larson
--   Version 1.0 3/26/2012 Scott Larson
--     Initial Public Release
--     Initial Public Release
--
--
-- @note This file has been modified from the original one found
-- @note This file has been modified from the original one found
-- on the web from: <https://eewiki.net/pages/viewpage.action?pageId=28279002>
-- on the web from: <https://eewiki.net/pages/viewpage.action?pageId=28279002>
--
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
 
 
library ieee;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_std.all;
 
 
entity ps2_debounce is
entity ps2_debounce is
        generic(counter_size:  integer := 19); --counter size (19 bits gives 10.5ms with 50mhz clock)
        generic(counter_size:  integer := 19); --counter size (19 bits gives 10.5ms with 50MHz clock)
        port(
        port(
                clk:    in  std_ulogic;
                clk:    in  std_ulogic;
                button: in  std_ulogic;  --input signal to be debounced
                button: in  std_ulogic;  --input signal to be debounced
                result: out std_ulogic := '0'); --debounced signal
                result: out std_ulogic := '0'); --debounced signal
end entity;
end entity;
 
 
architecture rtl of ps2_debounce is
architecture rtl of ps2_debounce is
        signal flipflops:   std_ulogic_vector(1 downto 0); --input flip flops
        signal flipflops:   std_ulogic_vector(1 downto 0); --input flip flops
        signal counter_set: std_ulogic;                    --sync reset to zero
        signal counter_set: std_ulogic;                    --sync reset to zero
        signal counter_out: unsigned(counter_size downto 0) := (others => '0'); --counter output
        signal counter_out: unsigned(counter_size downto 0) := (others => '0'); --counter output
begin
begin
 
 
        counter_set <= flipflops(0) xor flipflops(1);   --determine when to start/reset counter
        counter_set <= flipflops(0) xor flipflops(1);   --determine when to start/reset counter
 
 
        process(clk)
        process(clk)
        begin
        begin
                if rising_edge(clk) then
                if rising_edge(clk) then
                        flipflops(0) <= button;
                        flipflops(0) <= button;
                        flipflops(1) <= flipflops(0);
                        flipflops(1) <= flipflops(0);
                        if(counter_set = '1') then                  --reset counter because input is changing
                        if counter_set = '1'  then                  --reset counter because input is changing
                                counter_out <= (others => '0');
                                counter_out <= (others => '0');
                        elsif(counter_out(counter_size) = '0') then --stable input time is not yet met
                        elsif counter_out(counter_size) = '0'  then --stable input time is not yet met
                                counter_out <= counter_out + 1;
                                counter_out <= counter_out + 1;
                        else                                        --stable input time is met
                        else                                        --stable input time is met
                                result <= flipflops(1);
                                result <= flipflops(1);
                        end if;
                        end if;
                end if;
                end if;
        end process;
        end process;
end;
end;
 
 
 
 

powered by: WebSVN 2.1.0

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