⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 key_interface.vhd

📁 many application on kit SP-3: VGA, digital clock, counter, interface PS2....
💻 VHD
字号:
library IEEE;use IEEE.std_logic_1164.all;use IEEE.numeric_std.all;package key_Inter_pckg is  component key_interface --100_000    generic( FREQ : natural := 50000 );  -- frequency of the main clock (KHz)    port( clk      : in  std_logic;         -- main clock			rst      : in  std_logic;         -- asynchronous reset			ps2_clk  : in  std_logic;         -- clock from keyboard			ps2_data : in  std_logic;         -- data from keyboard			scancode : out std_logic_vector(7 downto 0);  -- key scancode			parity   : out std_logic;         -- parity bit for scancode			busy     : out std_logic;         -- busy receiving scancode			rdy      : buffer std_logic;         -- scancode ready pulse			error    : out std_logic   );       -- error receiving scancode end component ;end key_Inter_pckg;library IEEE;use IEEE.std_logic_1164.all;use IEEE.numeric_std.all;entity key_interface is --100_000  generic(FREQ : natural := 50000  );   -- frequency of the main clock (KHz)   port( clk      : in  std_logic;           -- main clock		 rst      : in  std_logic;           -- asynchronous reset		 ps2_clk  : in  std_logic;           -- clock from keyboard		 ps2_data : in  std_logic;           -- data from keyboard		 scancode : out std_logic_vector(7 downto 0);  -- key scancode		 parity   : out std_logic;           -- parity bit for scancode		 busy     : out std_logic;           -- busy receiving scancode		 rdy      : buffer std_logic;           -- scancode ready pulse		 error    : out std_logic   );         -- error receiving scancodeend key_interface;architecture behave of key_interface is  constant YES         : std_logic                    := '1';  constant NO          : std_logic                    := '0';  constant PS2_FREQ    : natural                      := 10;  -- keyboard clock frequency (KHz)  constant TIMEOUT     : natural                      := FREQ / PS2_FREQ;  -- ps2_clk quiet timeout  constant KEY_RELEASE : std_logic_vector(7 downto 0) := "11110000";  -- scancode sent when key is released  signal timer_x, timer_r     : natural range 0 to TIMEOUT;  -- counts time since last PS/2 clock edge  signal bitcnt_x, bitcnt_r   : natural range 0 to 11;  -- counts number of received scancode bits  signal ps2_clk_x, ps2_clk_r : std_logic_vector(5 downto 1);  -- PS/2 clock synchronization / edge detect shift register  signal ps2_clk_fall_edge    : std_logic;  -- pulses on falling edge of PS/2 clock  signal ps2_clk_rise_edge    : std_logic;  -- pulses on rising edge of PS/2 clock  signal ps2_clk_edge         : std_logic;  -- pulses on either edge of PS/2 clock  signal ps2_clk_quiet        : std_logic;  -- pulses when no edges on PS/2 clock for TIMEOUT  signal sc_x, sc_r           : std_logic_vector(9 downto 0);  -- scancode shift register  signal keyrel_x, keyrel_r   : std_logic;  -- this flag is set when the key release scancode is received  signal scancode_rdy         : std_logic;  -- indicates when any scancode has been received  signal rdy_x, rdy_r         : std_logic;  -- this flag is set when scancode for the pressed key is ready  signal error_x, error_r     : std_logic;  -- this flag is set when an error occursbegin  -- shift the level on the PS/2 clock into a shift register  ps2_clk_x <= ps2_clk_r(4 downto 1) & ps2_clk;  -- look at the PS/2 clock levels stored in the shift register and find rising or falling edges  ps2_clk_fall_edge <= YES when ps2_clk_r(5 downto 2) = "1100" else NO;  ps2_clk_rise_edge <= YES when ps2_clk_r(5 downto 2) = "0011" else NO;  ps2_clk_edge      <= ps2_clk_fall_edge or ps2_clk_rise_edge;  -- shift the keyboard scancode into the shift register on the falling edge of the PS/2 clock  sc_x <= ps2_data & sc_r(9 downto 1) when ps2_clk_fall_edge = YES else sc_r;  -- clear the timer right after a PS/2 clock edge and then keep incrementing it until the next edge  timer_x <= 0 when ps2_clk_edge = YES else timer_r + 1;  -- indicate when the PS/2 clock has stopped pulsing and is at a high level.  ps2_clk_quiet <= YES when timer_r = TIMEOUT and ps2_clk_r(2) = '1' else NO;  -- increment the bit counter on each falling edge of the PS/2 clock.  -- reset the bit counter if the PS/2 clock stops pulsing or if there was an error receiving the scancode.  -- otherwise, keep the bit counter unchanged.  bitcnt_x <= bitcnt_r + 1 when ps2_clk_fall_edge = YES              else              0            when ps2_clk_quiet = YES or error_r = YES else              bitcnt_r;  -- a scancode has been received if the bit counter is 11 and the PS/2 clock has stopped pulsing  scancode_rdy <= YES when bitcnt_r = 11 and ps2_clk_quiet = YES else NO;  -- look for the scancode sent when the key is released  keyrel_x <= YES when sc_r(scancode'range) = KEY_RELEASE and scancode_rdy = YES else              NO  when rdy_r = YES or error_r = YES                              else              keyrel_r;  -- the scancode for the pressed key arrives after receiving the key-release scancode   rdy_x <= YES when keyrel_r = YES and scancode_rdy = YES else NO;  -- indicate an error if the clock is low for too long or if it stops pulsing in the middle of a scancode  error_x <= YES when (timer_r = TIMEOUT and ps2_clk_r(2) = '0') or             (ps2_clk_quiet = YES and bitcnt_r/=11 and bitcnt_r/=0) else             error_r;  scancode <= sc_r(scancode'range);     -- output scancode  parity   <= sc_r(scancode'high+1);    -- output parity bit for the scancode  busy     <= YES when bitcnt_r/=0 else NO;  -- output busy signal when receiving a scancode  rdy      <= rdy_r;                    -- output scancode ready flag  error    <= error_r;                  -- output error flag  -- update the various registers  process(rst, clk)  begin    if rst = YES then      ps2_clk_r <= (others => '1');     -- start by assuming PS/2 clock has been high for a while      sc_r      <= (others => '0');     -- clear scancode register      keyrel_r  <= NO;                  -- key-release scancode has not been received yet      rdy_r     <= NO;                  -- no scancodes received yet      timer_r   <= 0;                   -- clear PS/2 clock pulse timer      bitcnt_r  <= 0;                   -- clear scancode bit counter      error_r   <= NO;                  -- clear any errors    elsif rising_edge(clk) then      ps2_clk_r <= ps2_clk_x;      sc_r      <= sc_x;      keyrel_r  <= keyrel_x;      rdy_r     <= rdy_x;      timer_r   <= timer_x;      bitcnt_r  <= bitcnt_x;      error_r   <= error_x;    end if;  end process;end behave;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -