//***************************************************************************** //* * //* Module: Altera_UP_PS2_Command_Out * //* Description: * //* This module sends commands out to the PS2 core. * //* * //*****************************************************************************/ module Altera_UP_PS2_Command_Out ( // Inputs clk, reset, the_command, send_command, ps2_clk_posedge, ps2_clk_negedge, // Bidirectionals PS2_CLK, PS2_DAT, // Outputs command_was_sent, error_communication_timed_out ); /***************************************************************************** * Parameter Declarations * *****************************************************************************/ // Timing info for initiating Host-to-Device communication // when using a 50MHz system clock parameter CLOCK_CYCLES_FOR_101US = 5050; parameter NUMBER_OF_BITS_FOR_101US = 13; parameter COUNTER_INCREMENT_FOR_101US = 13'h0001; // Timing info for start of transmission error // when using a 50MHz system clock parameter CLOCK_CYCLES_FOR_15MS = 750000; parameter NUMBER_OF_BITS_FOR_15MS = 20; parameter COUNTER_INCREMENT_FOR_15MS = 20'h00001; // Timing info for sending data error // when using a 50MHz system clock parameter CLOCK_CYCLES_FOR_2MS = 100000; parameter NUMBER_OF_BITS_FOR_2MS = 17; parameter COUNTER_INCREMENT_FOR_2MS = 17'h00001; /***************************************************************************** * Port Declarations * *****************************************************************************/ input clk; input reset; input [7:0] the_command; input send_command; input ps2_clk_posedge; input ps2_clk_negedge; inout PS2_CLK; inout PS2_DAT; output reg command_was_sent; output reg error_communication_timed_out; /***************************************************************************** * Constant Declarations * *****************************************************************************/ // states parameter PS2_STATE_0_IDLE = 3'h0, PS2_STATE_1_INITIATE_COMMUNICATION = 3'h1, PS2_STATE_2_WAIT_FOR_CLOCK = 3'h2, PS2_STATE_3_TRANSMIT_DATA = 3'h3, PS2_STATE_4_TRANSMIT_STOP_BIT = 3'h4, PS2_STATE_5_RECEIVE_ACK_BIT = 3'h5, PS2_STATE_6_COMMAND_WAS_SENT = 3'h6, PS2_STATE_7_TRANSMISSION_ERROR = 3'h7; /***************************************************************************** * Internal wires and registers Declarations * *****************************************************************************/ // Internal Registers reg [3:0] cur_bit; reg [8:0] ps2_command; reg [NUMBER_OF_BITS_FOR_101US:1] command_initiate_counter; reg [NUMBER_OF_BITS_FOR_15MS:1] waiting_counter; reg [NUMBER_OF_BITS_FOR_2MS:1] transfer_counter; // State Machine Registers reg [2:0] ns_ps2_transmitter; reg [2:0] s_ps2_transmitter; /***************************************************************************** * Finite State Machine(s) * *****************************************************************************/ always @(posedge clk) begin if (reset == 1'b1) s_ps2_transmitter <= PS2_STATE_0_IDLE; else s_ps2_transmitter <= ns_ps2_transmitter; end always @(*) begin // Defaults ns_ps2_transmitter = PS2_STATE_0_IDLE; case (s_ps2_transmitter) PS2_STATE_0_IDLE: begin if (send_command == 1'b1) ns_ps2_transmitter = PS2_STATE_1_INITIATE_COMMUNICATION; else ns_ps2_transmitter = PS2_STATE_0_IDLE; end PS2_STATE_1_INITIATE_COMMUNICATION: begin if (command_initiate_counter == CLOCK_CYCLES_FOR_101US) ns_ps2_transmitter = PS2_STATE_2_WAIT_FOR_CLOCK; else ns_ps2_transmitter = PS2_STATE_1_INITIATE_COMMUNICATION; end PS2_STATE_2_WAIT_FOR_CLOCK: begin if (ps2_clk_negedge == 1'b1) ns_ps2_transmitter = PS2_STATE_3_TRANSMIT_DATA; else if (waiting_counter == CLOCK_CYCLES_FOR_15MS) ns_ps2_transmitter = PS2_STATE_7_TRANSMISSION_ERROR; else ns_ps2_transmitter = PS2_STATE_2_WAIT_FOR_CLOCK; end PS2_STATE_3_TRANSMIT_DATA: begin if ((cur_bit == 4'd8) && (ps2_clk_negedge == 1'b1)) ns_ps2_transmitter = PS2_STATE_4_TRANSMIT_STOP_BIT; else if (transfer_counter == CLOCK_CYCLES_FOR_2MS) ns_ps2_transmitter = PS2_STATE_7_TRANSMISSION_ERROR; else ns_ps2_transmitter = PS2_STATE_3_TRANSMIT_DATA; end PS2_STATE_4_TRANSMIT_STOP_BIT: begin if (ps2_clk_negedge == 1'b1) ns_ps2_transmitter = PS2_STATE_5_RECEIVE_ACK_BIT; else if (transfer_counter == CLOCK_CYCLES_FOR_2MS) ns_ps2_transmitter = PS2_STATE_7_TRANSMISSION_ERROR; else ns_ps2_transmitter = PS2_STATE_4_TRANSMIT_STOP_BIT; end PS2_STATE_5_RECEIVE_ACK_BIT: begin if (ps2_clk_posedge == 1'b1) ns_ps2_transmitter = PS2_STATE_6_COMMAND_WAS_SENT; else if (transfer_counter == CLOCK_CYCLES_FOR_2MS) ns_ps2_transmitter = PS2_STATE_7_TRANSMISSION_ERROR; else ns_ps2_transmitter = PS2_STATE_5_RECEIVE_ACK_BIT; end PS2_STATE_6_COMMAND_WAS_SENT: begin if (send_command == 1'b0) ns_ps2_transmitter = PS2_STATE_0_IDLE; else ns_ps2_transmitter = PS2_STATE_6_COMMAND_WAS_SENT; end PS2_STATE_7_TRANSMISSION_ERROR: begin if (send_command == 1'b0) ns_ps2_transmitter = PS2_STATE_0_IDLE; else ns_ps2_transmitter = PS2_STATE_7_TRANSMISSION_ERROR; end default: begin ns_ps2_transmitter = PS2_STATE_0_IDLE; end endcase end /***************************************************************************** * Sequential logic * *****************************************************************************/ always @(posedge clk) begin if (reset == 1'b1) ps2_command <= 9'h000; else if (s_ps2_transmitter == PS2_STATE_0_IDLE) ps2_command <= {(^the_command) ^ 1'b1, the_command}; end always @(posedge clk) begin if (reset == 1'b1) command_initiate_counter <= {NUMBER_OF_BITS_FOR_101US{1'b0}}; else if ((s_ps2_transmitter == PS2_STATE_1_INITIATE_COMMUNICATION) && (command_initiate_counter != CLOCK_CYCLES_FOR_101US)) command_initiate_counter <= command_initiate_counter + COUNTER_INCREMENT_FOR_101US; else if (s_ps2_transmitter != PS2_STATE_1_INITIATE_COMMUNICATION) command_initiate_counter <= {NUMBER_OF_BITS_FOR_101US{1'b0}}; end always @(posedge clk) begin if (reset == 1'b1) waiting_counter <= {NUMBER_OF_BITS_FOR_15MS{1'b0}}; else if ((s_ps2_transmitter == PS2_STATE_2_WAIT_FOR_CLOCK) && (waiting_counter != CLOCK_CYCLES_FOR_15MS)) waiting_counter <= waiting_counter + COUNTER_INCREMENT_FOR_15MS; else if (s_ps2_transmitter != PS2_STATE_2_WAIT_FOR_CLOCK) waiting_counter <= {NUMBER_OF_BITS_FOR_15MS{1'b0}}; end always @(posedge clk) begin if (reset == 1'b1) transfer_counter <= {NUMBER_OF_BITS_FOR_2MS{1'b0}}; else begin if ((s_ps2_transmitter == PS2_STATE_3_TRANSMIT_DATA) || (s_ps2_transmitter == PS2_STATE_4_TRANSMIT_STOP_BIT) || (s_ps2_transmitter == PS2_STATE_5_RECEIVE_ACK_BIT)) begin if (transfer_counter != CLOCK_CYCLES_FOR_2MS) transfer_counter <= transfer_counter + COUNTER_INCREMENT_FOR_2MS; end else transfer_counter <= {NUMBER_OF_BITS_FOR_2MS{1'b0}}; end end always @(posedge clk) begin if (reset == 1'b1) cur_bit <= 4'h0; else if ((s_ps2_transmitter == PS2_STATE_3_TRANSMIT_DATA) && (ps2_clk_negedge == 1'b1)) cur_bit <= cur_bit + 4'h1; else if (s_ps2_transmitter != PS2_STATE_3_TRANSMIT_DATA) cur_bit <= 4'h0; end always @(posedge clk) begin if (reset == 1'b1) command_was_sent <= 1'b0; else if (s_ps2_transmitter == PS2_STATE_6_COMMAND_WAS_SENT) command_was_sent <= 1'b1; else if (send_command == 1'b0) command_was_sent <= 1'b0; end always @(posedge clk) begin if (reset == 1'b1) error_communication_timed_out <= 1'b0; else if (s_ps2_transmitter == PS2_STATE_7_TRANSMISSION_ERROR) error_communication_timed_out <= 1'b1; else if (send_command == 1'b0) error_communication_timed_out <= 1'b0; end /***************************************************************************** * Combinational logic * *****************************************************************************/ assign PS2_CLK = (s_ps2_transmitter == PS2_STATE_1_INITIATE_COMMUNICATION) ? 1'b0 : 1'bz; assign PS2_DAT = (s_ps2_transmitter == PS2_STATE_3_TRANSMIT_DATA) ? ps2_command[cur_bit] : (s_ps2_transmitter == PS2_STATE_2_WAIT_FOR_CLOCK) ? 1'b0 : ((s_ps2_transmitter == PS2_STATE_1_INITIATE_COMMUNICATION) && (command_initiate_counter[NUMBER_OF_BITS_FOR_101US] == 1'b1)) ? 1'b0 : 1'bz; endmodule
29 июн, 2020
© 2007-2023 Мутил психичный блин