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

Subversion Repositories ps2

[/] [ps2/] [tags/] [rel_9/] [rtl/] [verilog/] [ps2_keyboard.v] - Diff between revs 24 and 25

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 24 Rev 25
Line 252... Line 252...
// Input "synchronizing" logic -- synchronizes the inputs to the state
// Input "synchronizing" logic -- synchronizes the inputs to the state
// machine clock, thus avoiding errors related to
// machine clock, thus avoiding errors related to
// spurious state machine transitions.
// spurious state machine transitions.
always @(posedge clk)
always @(posedge clk)
begin
begin
  ps2_clk_ms <= ps2_clk_i;
  ps2_clk_ms <= #1 ps2_clk_i;
  ps2_data_ms <= ps2_data_i;
  ps2_data_ms <= #1  ps2_data_i;
 
 
  ps2_clk_s <= ps2_clk_ms;
  ps2_clk_s <= #1 ps2_clk_ms;
  ps2_data_s <= ps2_data_ms;
  ps2_data_s <= #1 ps2_data_ms;
 
 
end
end
 
 
// State register
// State register
always @(posedge clk or posedge reset)
always @(posedge clk or posedge reset)
begin : m1_state_register
begin : m1_state_register
  if (reset) m1_state <= m1_rx_clk_h;
  if (reset) m1_state <= #1 m1_rx_clk_h;
  else m1_state <= m1_next_state;
  else m1_state <= #1 m1_next_state;
end
end
 
 
// State transition logic
// State transition logic
always @(m1_state
always @(m1_state
         or q
         or q
Line 280... Line 280...
         or timer_5usec_done
         or timer_5usec_done
         )
         )
begin : m1_state_logic
begin : m1_state_logic
 
 
  // Output signals default to this value, unless changed in a state condition.
  // Output signals default to this value, unless changed in a state condition.
  ps2_clk_hi_z <= 1;
  ps2_clk_hi_z <= #1 1;
  ps2_data_hi_z <= 1;
  ps2_data_hi_z <= #1 1;
  tx_error_no_keyboard_ack <= 0;
  tx_error_no_keyboard_ack <= #1 1'b0;
  enable_timer_60usec <= 0;
  enable_timer_60usec <= #1 0;
  enable_timer_5usec <= 0;
  enable_timer_5usec <= #1 0;
 
 
  case (m1_state)
  case (m1_state)
 
 
    m1_rx_clk_h :
    m1_rx_clk_h :
      begin
      begin
        enable_timer_60usec <= 1;
        enable_timer_60usec <= #1 1;
        if (tx_write) m1_next_state <= m1_tx_reset_timer;
        if (tx_write) m1_next_state <= #1 m1_tx_reset_timer;
        else if (~ps2_clk_s) m1_next_state <= m1_rx_falling_edge_marker;
        else if (~ps2_clk_s) m1_next_state <= #1 m1_rx_falling_edge_marker;
        else m1_next_state <= m1_rx_clk_h;
        else m1_next_state <= #1 m1_rx_clk_h;
      end
      end
 
 
    m1_rx_falling_edge_marker :
    m1_rx_falling_edge_marker :
      begin
      begin
        enable_timer_60usec <= 0;
        enable_timer_60usec <= #1 0;
        m1_next_state <= m1_rx_clk_l;
        m1_next_state <= #1 m1_rx_clk_l;
      end
      end
 
 
    m1_rx_rising_edge_marker :
    m1_rx_rising_edge_marker :
      begin
      begin
        enable_timer_60usec <= 0;
        enable_timer_60usec <= #1 0;
        m1_next_state <= m1_rx_clk_h;
        m1_next_state <= #1 m1_rx_clk_h;
      end
      end
 
 
 
 
    m1_rx_clk_l :
    m1_rx_clk_l :
      begin
      begin
        enable_timer_60usec <= 1;
        enable_timer_60usec <= #1 1;
        if (tx_write) m1_next_state <= m1_tx_reset_timer;
        if (tx_write) m1_next_state <= #1 m1_tx_reset_timer;
        else if (ps2_clk_s) m1_next_state <= m1_rx_rising_edge_marker;
        else if (ps2_clk_s) m1_next_state <= #1 m1_rx_rising_edge_marker;
        else m1_next_state <= m1_rx_clk_l;
        else m1_next_state <= #1 m1_rx_clk_l;
      end
      end
 
 
    m1_tx_reset_timer:
    m1_tx_reset_timer:
      begin
      begin
        enable_timer_60usec <= 0;
        enable_timer_60usec <= #1 0;
        m1_next_state <= m1_tx_force_clk_l;
        m1_next_state <= #1 m1_tx_force_clk_l;
      end
      end
 
 
    m1_tx_force_clk_l :
    m1_tx_force_clk_l :
      begin
      begin
        enable_timer_60usec <= 1;
        enable_timer_60usec <= #1 1;
        ps2_clk_hi_z <= 0;  // Force the ps2_clk line low.
        ps2_clk_hi_z <= #1 0;  // Force the ps2_clk line low.
        if (timer_60usec_done) m1_next_state <= m1_tx_first_wait_clk_h;
        if (timer_60usec_done) m1_next_state <= #1 m1_tx_first_wait_clk_h;
        else m1_next_state <= m1_tx_force_clk_l;
        else m1_next_state <= #1 m1_tx_force_clk_l;
      end
      end
 
 
    m1_tx_first_wait_clk_h :
    m1_tx_first_wait_clk_h :
      begin
      begin
        enable_timer_5usec <= 1;
        enable_timer_5usec <= #1 1;
        ps2_data_hi_z <= 0;        // Start bit.
        ps2_data_hi_z <= #1 0;        // Start bit.
        if (~ps2_clk_s && timer_5usec_done)
        if (~ps2_clk_s && timer_5usec_done)
          m1_next_state <= m1_tx_clk_l;
          m1_next_state <= #1 m1_tx_clk_l;
        else
        else
          m1_next_state <= m1_tx_first_wait_clk_h;
          m1_next_state <= #1 m1_tx_first_wait_clk_h;
      end
      end
 
 
    // This state must be included because the device might possibly
    // This state must be included because the device might possibly
    // delay for up to 10 milliseconds before beginning its clock pulses.
    // delay for up to 10 milliseconds before beginning its clock pulses.
    // During that waiting time, we cannot drive the data (q[0]) because it
    // 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
    // is possibly 1, which would cause the keyboard to abort its receive
    // and the expected clocks would then never be generated.
    // and the expected clocks would then never be generated.
    m1_tx_first_wait_clk_l :
    m1_tx_first_wait_clk_l :
      begin
      begin
        ps2_data_hi_z <= 0;
        ps2_data_hi_z <= #1 0;
        if (~ps2_clk_s) m1_next_state <= m1_tx_clk_l;
        if (~ps2_clk_s) m1_next_state <= #1 m1_tx_clk_l;
        else m1_next_state <= m1_tx_first_wait_clk_l;
        else m1_next_state <= #1 m1_tx_first_wait_clk_l;
      end
      end
 
 
    m1_tx_wait_clk_h :
    m1_tx_wait_clk_h :
      begin
      begin
        enable_timer_5usec <= 1;
        enable_timer_5usec <= #1 1;
        ps2_data_hi_z <= q[0];
        ps2_data_hi_z <= #1 q[0];
        if (ps2_clk_s && timer_5usec_done)
        if (ps2_clk_s && timer_5usec_done)
          m1_next_state <= m1_tx_rising_edge_marker;
          m1_next_state <= #1 m1_tx_rising_edge_marker;
        else
        else
          m1_next_state <= m1_tx_wait_clk_h;
          m1_next_state <= #1 m1_tx_wait_clk_h;
      end
      end
 
 
    m1_tx_rising_edge_marker :
    m1_tx_rising_edge_marker :
      begin
      begin
        ps2_data_hi_z <= q[0];
        ps2_data_hi_z <= #1 q[0];
        m1_next_state <= m1_tx_clk_h;
        m1_next_state <= #1 m1_tx_clk_h;
      end
      end
 
 
    m1_tx_clk_h :
    m1_tx_clk_h :
      begin
      begin
        ps2_data_hi_z <= q[0];
        ps2_data_hi_z <= #1 q[0];
        if (tx_shifting_done) m1_next_state <= m1_tx_wait_keyboard_ack;
        if (tx_shifting_done) m1_next_state <= #1 m1_tx_wait_keyboard_ack;
        else if (~ps2_clk_s) m1_next_state <= m1_tx_clk_l;
        else if (~ps2_clk_s) m1_next_state <= #1 m1_tx_clk_l;
        else m1_next_state <= m1_tx_clk_h;
        else m1_next_state <= #1 m1_tx_clk_h;
      end
      end
 
 
    m1_tx_clk_l :
    m1_tx_clk_l :
      begin
      begin
        ps2_data_hi_z <= q[0];
        ps2_data_hi_z <= #1 q[0];
        if (ps2_clk_s) m1_next_state <= m1_tx_wait_clk_h;
        if (ps2_clk_s) m1_next_state <= #1 m1_tx_wait_clk_h;
        else m1_next_state <= m1_tx_clk_l;
        else m1_next_state <= #1 m1_tx_clk_l;
      end
      end
 
 
    m1_tx_wait_keyboard_ack :
    m1_tx_wait_keyboard_ack :
      begin
      begin
        if (~ps2_clk_s && ps2_data_s)
        if (~ps2_clk_s && ps2_data_s)
          m1_next_state <= m1_tx_error_no_keyboard_ack;
          m1_next_state <= #1 m1_tx_error_no_keyboard_ack;
        else if (~ps2_clk_s && ~ps2_data_s)
        else if (~ps2_clk_s && ~ps2_data_s)
          m1_next_state <= m1_tx_done_recovery;
          m1_next_state <= #1 m1_tx_done_recovery;
        else m1_next_state <= m1_tx_wait_keyboard_ack;
        else m1_next_state <= #1 m1_tx_wait_keyboard_ack;
      end
      end
 
 
    m1_tx_done_recovery :
    m1_tx_done_recovery :
      begin
      begin
        if (ps2_clk_s && ps2_data_s) m1_next_state <= m1_rx_clk_h;
        if (ps2_clk_s && ps2_data_s) m1_next_state <= #1 m1_rx_clk_h;
        else m1_next_state <= m1_tx_done_recovery;
        else m1_next_state <= #1 m1_tx_done_recovery;
      end
      end
 
 
    m1_tx_error_no_keyboard_ack :
    m1_tx_error_no_keyboard_ack :
      begin
      begin
        tx_error_no_keyboard_ack <= 1;
        tx_error_no_keyboard_ack <= #1 1;
        if (ps2_clk_s && ps2_data_s) m1_next_state <= m1_rx_clk_h;
        if (ps2_clk_s && ps2_data_s) m1_next_state <= #1 m1_rx_clk_h;
        else m1_next_state <= m1_tx_error_no_keyboard_ack;
        else m1_next_state <= #1 m1_tx_error_no_keyboard_ack;
      end
      end
 
 
    default : m1_next_state <= m1_rx_clk_h;
    default : m1_next_state <= #1 m1_rx_clk_h;
  endcase
  endcase
end
end
 
 
// State register
// State register
always @(posedge clk or posedge reset)
always @(posedge clk or posedge reset)
begin : m2_state_register
begin : m2_state_register
  if (reset) m2_state <= m2_rx_data_ready_ack;
  if (reset) m2_state <= #1 m2_rx_data_ready_ack;
  else m2_state <= m2_next_state;
  else m2_state <= #1 m2_next_state;
end
end
 
 
// State transition logic
// State transition logic
always @(m2_state or rx_output_strobe or rx_read)
always @(m2_state or rx_output_strobe or rx_read)
begin : m2_state_logic
begin : m2_state_logic
  case (m2_state)
  case (m2_state)
    m2_rx_data_ready_ack:
    m2_rx_data_ready_ack:
          begin
          begin
            rx_data_ready <= 1'b0;
            rx_data_ready <= #1 1'b0;
            if (rx_output_strobe) m2_next_state <= m2_rx_data_ready;
            if (rx_output_strobe) m2_next_state <= #1 m2_rx_data_ready;
            else m2_next_state <= m2_rx_data_ready_ack;
            else m2_next_state <= #1 m2_rx_data_ready_ack;
          end
          end
    m2_rx_data_ready:
    m2_rx_data_ready:
          begin
          begin
            rx_data_ready <= 1'b1;
            rx_data_ready <= #1 1'b1;
            if (rx_read) m2_next_state <= m2_rx_data_ready_ack;
            if (rx_read) m2_next_state <= #1 m2_rx_data_ready_ack;
            else m2_next_state <= m2_rx_data_ready;
            else m2_next_state <= #1 m2_rx_data_ready;
          end
          end
    default : m2_next_state <= m2_rx_data_ready_ack;
    default : m2_next_state <= #1 m2_rx_data_ready_ack;
  endcase
  endcase
end
end
 
 
// This is the bit counter
// This is the bit counter
always @(posedge clk or posedge reset)
always @(posedge clk or posedge reset)
begin
begin
  if ( reset) bit_count <= 0;
  if ( reset) bit_count <= #1 0;
  else if ( rx_shifting_done || (m1_state == m1_tx_wait_keyboard_ack)        // After tx is done.
  else if ( rx_shifting_done || (m1_state == m1_tx_wait_keyboard_ack)        // After tx is done.
      ) bit_count <= 0;  // normal reset
      ) bit_count <= #1 0;  // normal reset
  else if (timer_60usec_done
  else if (timer_60usec_done
           && (m1_state == m1_rx_clk_h)
           && (m1_state == m1_rx_clk_h)
           && (ps2_clk_s)
           && (ps2_clk_s)
      ) bit_count <= 0;  // rx watchdog timer reset
      ) bit_count <= #1 0;  // rx watchdog timer reset
  else if ( (m1_state == m1_rx_falling_edge_marker)   // increment for rx
  else if ( (m1_state == m1_rx_falling_edge_marker)   // increment for rx
           ||(m1_state == m1_tx_rising_edge_marker)   // increment for tx
           ||(m1_state == m1_tx_rising_edge_marker)   // increment for tx
           )
           )
    bit_count <= bit_count + 1;
    bit_count <= #1 bit_count + 1;
end
end
// This signal is high for one clock at the end of the timer count.
// This signal is high for one clock at the end of the timer count.
assign rx_shifting_done = (bit_count == `TOTAL_BITS);
assign rx_shifting_done = (bit_count == `TOTAL_BITS);
assign tx_shifting_done = (bit_count == `TOTAL_BITS-1);
assign tx_shifting_done = (bit_count == `TOTAL_BITS-1);
 
 
Line 468... Line 468...
assign tx_parity_bit = ~^tx_data;
assign tx_parity_bit = ~^tx_data;
 
 
// This is the shift register
// This is the shift register
always @(posedge clk or posedge reset)
always @(posedge clk or posedge reset)
begin
begin
  if (reset) q <= 0;
  if (reset) q <= #1 0;
  else if (tx_write_ack_o) q <= {1'b1,tx_parity_bit,tx_data,1'b0};
  else if (tx_write_ack_o) q <= #1 {1'b1,tx_parity_bit,tx_data,1'b0};
  else if ( (m1_state == m1_rx_falling_edge_marker)
  else if ( (m1_state == m1_rx_falling_edge_marker)
           ||(m1_state == m1_tx_rising_edge_marker) )
           ||(m1_state == m1_tx_rising_edge_marker) )
    q <= {ps2_data_s,q[`TOTAL_BITS-1:1]};
    q <= #1 {ps2_data_s,q[`TOTAL_BITS-1:1]};
end
end
 
 
// This is the 60usec timer counter
// This is the 60usec timer counter
always @(posedge clk)
always @(posedge clk)
begin
begin
  if (~enable_timer_60usec) timer_60usec_count <= 0;
  if (~enable_timer_60usec) timer_60usec_count <= #1 0;
  else if ( timer_done && !timer_60usec_done)
  else if ( timer_done && !timer_60usec_done)
         timer_60usec_count<= timer_60usec_count +1;
         timer_60usec_count<= #1 timer_60usec_count +1;
  end
  end
assign timer_60usec_done = (timer_60usec_count == (TIMER_60USEC_VALUE_PP ));
assign timer_60usec_done = (timer_60usec_count == (TIMER_60USEC_VALUE_PP ));
 
 
 
 
 
 
always @(posedge clk or posedge reset)
always @(posedge clk or posedge reset)
if (reset) timer_5usec <= 1;
if (reset) timer_5usec <= #1 1;
else if (!enable_timer_60usec) timer_5usec <= 1;
else if (!enable_timer_60usec) timer_5usec <= #1 1;
else if (timer_5usec == devide_reg_i)
else if (timer_5usec == devide_reg_i)
 begin
 begin
   timer_5usec <= 1;
   timer_5usec <= #1 1;
   timer_done  <= 1;
   timer_done  <= #1 1;
  end
  end
else
else
  begin
  begin
    timer_5usec<= timer_5usec +1;
    timer_5usec<= #1 timer_5usec +1;
    timer_done  <= 0;
    timer_done  <= #1 0;
 end
 end
 
 
// This is the 5usec timer counter
// This is the 5usec timer counter
always @(posedge clk)
always @(posedge clk)
begin
begin
  if (~enable_timer_5usec) timer_5usec_count <= 0;
  if (~enable_timer_5usec) timer_5usec_count <= #1 0;
  else if (~timer_5usec_done) timer_5usec_count <= timer_5usec_count + 1;
  else if (~timer_5usec_done) timer_5usec_count <= #1 timer_5usec_count + 1;
end
end
assign timer_5usec_done = (timer_5usec_count == devide_reg_i -1);
assign timer_5usec_done = (timer_5usec_count == devide_reg_i -1);
 
 
 
 
// Create the signals which indicate special scan codes received.
// Create the signals which indicate special scan codes received.
Line 518... Line 518...
// Store the special scan code status bits
// Store the special scan code status bits
// Not the final output, but an intermediate storage place,
// Not the final output, but an intermediate storage place,
// until the entire set of output data can be assembled.
// until the entire set of output data can be assembled.
always @(posedge clk or posedge reset)
always @(posedge clk or posedge reset)
begin
begin
  if (reset) hold_released <= 0;
  if (reset) hold_released <= #1 0;
  else if (rx_output_event)
  else if (rx_output_event)
  begin
  begin
    hold_released <= 0;
    hold_released <= #1 0;
  end
  end
  else
  else
  begin
  begin
    if (rx_shifting_done && released) hold_released <= 1;
    if (rx_shifting_done && released) hold_released <= #1 1;
  end
  end
end
end
 
 
// Output the special scan code flags, the scan code and the ascii
// Output the special scan code flags, the scan code and the ascii
always @(posedge clk or posedge reset)
always @(posedge clk or posedge reset)
begin
begin
  if (reset)
  if (reset)
  begin
  begin
    rx_released <= 0;
    rx_released <= #1 0;
    rx_scan_code <= 0;
    rx_scan_code <= #1 0;
  end
  end
  else if (rx_output_strobe)
  else if (rx_output_strobe)
  begin
  begin
    rx_released <= hold_released;
    rx_released <= #1 hold_released;
    rx_scan_code <= q[8:1];
    rx_scan_code <= #1 q[8:1];
  end
  end
end
end
 
 
// Store the final rx output data only when all extend and release codes
// Store the final rx output data only when all extend and release codes
// are received and the next (actual key) scan code is also ready.
// are received and the next (actual key) scan code is also ready.

powered by: WebSVN 2.1.0

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