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

📄 ps2_keyboard_interface.vhd

📁 BurchED B5-X300 Spartan2e using XC2S300e device Top level file for 6809 compatible system on a chi
💻 VHD
📖 第 1 页 / 共 3 页
字号:

-- State register
m1_state_register : process( clk, reset, m1_state )
begin
  if clk'event and clk='1' then
    if (reset = '1') then
	    m1_state <= m1_rx_clk_h;
    else 
	    m1_state <= m1_next_state;
    end if;
  end if;
end process;

m1_state_logic : process( m1_state, q,
                          tx_shifting_done, tx_write, 
								  ps2_clk_s, ps2_data_s,
								  timer_60usec_done, timer_5usec_done )
begin
  -- Output signals default to this value, unless changed in a state condition.
  ps2_clk_hi_z             <= '1';
  ps2_data_hi_z            <= '1';
  tx_error_no_keyboard_ack <= '0';
  enable_timer_60usec      <= '0';
  enable_timer_5usec       <= '0';

  case (m1_state) is
  when m1_rx_clk_h =>
        enable_timer_60usec <= '1';
        if (tx_write = '1') then
		      m1_next_state <= m1_tx_reset_timer;
        elsif (ps2_clk_s = '0') then
		      m1_next_state <= m1_rx_falling_edge_marker;
        else 
		      m1_next_state <= m1_rx_clk_h;
        end if;
      
  when m1_rx_falling_edge_marker =>
        enable_timer_60usec <= '0';
        m1_next_state <= m1_rx_clk_l;

  when m1_rx_rising_edge_marker =>
        enable_timer_60usec <= '0';
        m1_next_state <= m1_rx_clk_h;


  when m1_rx_clk_l =>
        enable_timer_60usec <= '1';
        if (tx_write = '1') then
		     m1_next_state <= m1_tx_reset_timer;
        elsif (ps2_clk_s = '1') then
		     m1_next_state <= m1_rx_rising_edge_marker;
        else 
		     m1_next_state <= m1_rx_clk_l;
        end if;

  when m1_tx_reset_timer =>
        enable_timer_60usec <= '0';
        m1_next_state <= m1_tx_force_clk_l;

  when m1_tx_force_clk_l =>
        enable_timer_60usec <= '1';
        ps2_clk_hi_z <= '0';  -- Force the ps2_clk line low.
        if (timer_60usec_done = '1') then
		     m1_next_state <= m1_tx_first_wait_clk_h;
        else 
		     m1_next_state <= m1_tx_force_clk_l;
        end	if;

  when m1_tx_first_wait_clk_h =>
        enable_timer_5usec <= '1';
        ps2_data_hi_z <= '0';        -- Start bit.
        if (ps2_clk_s = '0') and (timer_5usec_done = '1') then
          m1_next_state <= m1_tx_clk_l;
        else
          m1_next_state <= m1_tx_first_wait_clk_h;
        end	if;
      
    -- This state must be included because the device might possibly
    -- delay for up to 10 milliseconds before beginning its clock pulses.
    -- During that waiting time, we cannot drive the data (q[0]) because it
    -- is possibly 1, which would cause the keyboard to abort its receive
    -- and the expected clocks would then never be generated.
  when m1_tx_first_wait_clk_l =>
        ps2_data_hi_z <= '0';
        if (ps2_clk_s = '0') then
		     m1_next_state <= m1_tx_clk_l;
        else 
		     m1_next_state <= m1_tx_first_wait_clk_l;
        end	if;

  when m1_tx_wait_clk_h =>
        enable_timer_5usec <= '1';
        ps2_data_hi_z <= q(0);
        if (ps2_clk_s = '1') and (timer_5usec_done = '1') then
          m1_next_state <= m1_tx_rising_edge_marker;
        else
          m1_next_state <= m1_tx_wait_clk_h;
        end	if;

  when m1_tx_rising_edge_marker =>
        ps2_data_hi_z <= q(0);
        m1_next_state <= m1_tx_clk_h;

  when m1_tx_clk_h =>
        ps2_data_hi_z <= q(0);
        if (tx_shifting_done = '1') then
		     m1_next_state <= m1_tx_wait_keyboard_ack;
        elsif (ps2_clk_s = '0') then
		     m1_next_state <= m1_tx_clk_l;
        else
		     m1_next_state <= m1_tx_clk_h;
        end	if;

  when m1_tx_clk_l =>
        ps2_data_hi_z <= q(0);
        if (ps2_clk_s = '1') then
		     m1_next_state <= m1_tx_wait_clk_h;
        else
		     m1_next_state <= m1_tx_clk_l;
        end	if;

  when m1_tx_wait_keyboard_ack =>
        if (ps2_clk_s = '0') and (ps2_data_s = '1') then
           m1_next_state <= m1_tx_error_no_keyboard_ack;
        elsif (ps2_clk_s = '0') and (ps2_data_s = '0') then
           m1_next_state <= m1_tx_done_recovery;
        else 
		     m1_next_state <= m1_tx_wait_keyboard_ack;
        end	if;

  when m1_tx_done_recovery =>
        if (ps2_clk_s = '1') and (ps2_data_s = '1') then
		     m1_next_state <= m1_rx_clk_h;
        else 
		     m1_next_state <= m1_tx_done_recovery;
        end	if;

  when m1_tx_error_no_keyboard_ack =>
        tx_error_no_keyboard_ack <= '1';
        if (ps2_clk_s = '1') and (ps2_data_s ='1') then
		     m1_next_state <= m1_rx_clk_h;
        else 
		     m1_next_state <= m1_tx_error_no_keyboard_ack;
        end	if;

  when others =>
	     m1_next_state <= m1_rx_clk_h;
  end case;
end process;

-- State register
m2_state_register	: process( clk )
begin
  if clk'event and clk='1' then
     if (reset = '1') then
	    m2_state <= m2_rx_data_ready_ack;
     else 
	    m2_state <= m2_next_state;
     end if;
  end if;
end process;

-- State transition logic
m2_state_logic	: process(m2_state, rx_output_strobe, rx_read)
begin 
  case (m2_state)	is
    when  m2_rx_data_ready_ack =>
            rx_data_ready <= '0';
            if (rx_output_strobe = '1') then
				   m2_next_state <= m2_rx_data_ready;
            else 
				   m2_next_state <= m2_rx_data_ready_ack;
            end if;

    when m2_rx_data_ready =>
            rx_data_ready <= '1';
            if (rx_read = '1') then
				   m2_next_state <= m2_rx_data_ready_ack;
            else 
				   m2_next_state <= m2_rx_data_ready;
            end if;

    when others =>
	          m2_next_state <= m2_rx_data_ready_ack;
  end case;
end process;

-- This is the bit counter
bit_counter: process(clk, reset, m1_state, bit_count )
begin
  if clk'event and clk = '1' then
    if ( reset = '1' ) or
       ( rx_shifting_done = '1' ) or
       (m1_state = m1_tx_wait_keyboard_ack) then       -- After tx is done.
       bit_count <= "0000";  -- normal reset
    elsif (timer_60usec_done = '1' ) and
          (m1_state = m1_rx_clk_h)	and
          (ps2_clk_s = '1') then
       bit_count <= "0000";  -- rx watchdog timer reset
    elsif (m1_state = m1_rx_falling_edge_marker) or  -- increment for rx
          (m1_state = m1_tx_rising_edge_marker) then  -- increment for tx
       bit_count <= bit_count + 1;
    end if;
  end if;
end process;

assign: process( bit_count, tx_write, tx_write_ack_o, m1_state )
begin
  if (bit_count = TOTAL_BITS) then
     rx_shifting_done <= '1';
  else
     rx_shifting_done <= '0';
  end if;

  if (bit_count = (TOTAL_BITS-1)) then
     tx_shifting_done <= '1';
  else
     tx_shifting_done <= '0';
  end if;

-- This is the signal which enables loading of the shift register.
-- It also indicates "ack" to the device writing to the transmitter.
  if ((tx_write = '1') and (m1_state = m1_rx_clk_h)) or
     ((tx_write = '1') and (m1_state = m1_rx_clk_l)) then
     tx_write_ack_o <= '1';
  else 
     tx_write_ack_o <= '0';
  end if;
  tx_write_ack <= tx_write_ack_o;
end process;

-- This is the ODD parity bit for the transmitted word.
-- assign tx_parity_bit = ~^tx_data;
--
tx_parity_bit <= not( tx_data(7) xor tx_data(6) xor tx_data(5) xor tx_data(4) xor
                      tx_data(7) xor tx_data(6) xor tx_data(5) xor tx_data(4) );

-- This is the shift register
q_shift : process(clk, tx_write_ack_o, tx_parity_bit, tx_data,
                  m1_state, q, ps2_data_s, rx_shifting_done )
begin
  if clk'event and clk='1' then
    if (reset = '1') then
	    q <= "00000000000";
    elsif (tx_write_ack_o = '1') then
	    q <= "1" & tx_parity_bit & tx_data & "0";
    elsif ( (m1_state = m1_rx_falling_edge_marker)	or
            (m1_state = m1_tx_rising_edge_marker) ) then
       q <= ps2_data_s & q((TOTAL_BITS-1) downto 1);
    end if;
  end if;

-- Create the signals which indicate special scan codes received.
-- These are the "unlatched versions."
  if (q(8 downto 1) = EXTEND_CODE) and (rx_shifting_done = '1') then
    extended <= '1';
  else
    extended <= '0';
  end if;
  if (q(8 downto 1) = RELEASE_CODE) and (rx_shifting_done = '1') then
    released <= '1';
  else
    released <= '0';

⌨️ 快捷键说明

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