mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			176 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Verilog
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			176 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Verilog
		
	
	
		
			Executable File
		
	
	
	
	
| /*
 | |
|  *  PS2 Mouse Interface
 | |
|  *  Copyright (C) 2010  Donna Polehn <dpolehn@verizon.net>
 | |
|  *
 | |
|  *  This file is part of the Zet processor. This processor is free
 | |
|  *  hardware; you can redistribute it and/or modify it under the terms of
 | |
|  *  the GNU General Public License as published by the Free Software
 | |
|  *  Foundation; either version 3, or (at your option) any later version.
 | |
|  *
 | |
|  *  Zet is distrubuted in the hope that it will be useful, but WITHOUT
 | |
|  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 | |
|  *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
 | |
|  *  License for more details.
 | |
|  *
 | |
|  *  You should have received a copy of the GNU General Public License
 | |
|  *  along with Zet; see the file COPYING. If not, see
 | |
|  *  <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| 
 | |
| module ps2_mouse (
 | |
|     input clk,                // Clock Input
 | |
|     input reset,              // Reset Input
 | |
|     inout ps2_clk,            // PS2 Clock, Bidirectional
 | |
|     inout ps2_dat,            // PS2 Data, Bidirectional
 | |
| 
 | |
|     input  [7:0] the_command,        // Command to send to mouse
 | |
|     input        send_command,       // Signal to send
 | |
|     output       command_was_sent,   // Signal command finished sending
 | |
|     output       error_communication_timed_out,
 | |
| 
 | |
|     output [7:0] received_data,        // Received data
 | |
|     output       received_data_en,     // If 1 - new data has been received
 | |
|     output       start_receiving_data,
 | |
|     output       wait_for_incoming_data
 | |
|   );
 | |
| 
 | |
|   // --------------------------------------------------------------------
 | |
|   // Internal wires and registers Declarations
 | |
|   // --------------------------------------------------------------------
 | |
|   wire            ps2_clk_posedge;        // Internal Wires
 | |
|   wire            ps2_clk_negedge;
 | |
| 
 | |
|   reg    [7:0]    idle_counter;            // Internal Registers
 | |
|   reg             ps2_clk_reg;
 | |
|   reg             ps2_data_reg;
 | |
|   reg             last_ps2_clk;
 | |
| 
 | |
|   reg    [2:0]    ns_ps2_transceiver;        // State Machine Registers
 | |
|   reg    [2:0]    s_ps2_transceiver;
 | |
| 
 | |
|   // --------------------------------------------------------------------
 | |
|   // Constant Declarations
 | |
|   // --------------------------------------------------------------------
 | |
|   localparam  PS2_STATE_0_IDLE            = 3'h0,        // states
 | |
|               PS2_STATE_1_DATA_IN         = 3'h1,
 | |
|               PS2_STATE_2_COMMAND_OUT     = 3'h2,
 | |
|               PS2_STATE_3_END_TRANSFER    = 3'h3,
 | |
|               PS2_STATE_4_END_DELAYED     = 3'h4;
 | |
| 
 | |
|   // --------------------------------------------------------------------
 | |
|   // Finite State Machine(s)
 | |
|   // --------------------------------------------------------------------
 | |
|   always @(posedge clk) begin
 | |
|     if(reset == 1'b1) s_ps2_transceiver <= PS2_STATE_0_IDLE;
 | |
|     else              s_ps2_transceiver <= ns_ps2_transceiver;
 | |
|   end
 | |
| 
 | |
|   always @(*) begin
 | |
|     ns_ps2_transceiver = PS2_STATE_0_IDLE;        // Defaults
 | |
| 
 | |
|     case (s_ps2_transceiver)
 | |
|     PS2_STATE_0_IDLE:
 | |
|         begin
 | |
|             if((idle_counter == 8'hFF) && (send_command == 1'b1))
 | |
|                 ns_ps2_transceiver = PS2_STATE_2_COMMAND_OUT;
 | |
|             else if ((ps2_data_reg == 1'b0) && (ps2_clk_posedge == 1'b1))
 | |
|                 ns_ps2_transceiver = PS2_STATE_1_DATA_IN;
 | |
|             else ns_ps2_transceiver = PS2_STATE_0_IDLE;
 | |
|         end
 | |
|     PS2_STATE_1_DATA_IN:
 | |
|         begin
 | |
|             // if((received_data_en == 1'b1)  && (ps2_clk_posedge == 1'b1))
 | |
|             if((received_data_en == 1'b1))   ns_ps2_transceiver = PS2_STATE_0_IDLE;
 | |
|             else                             ns_ps2_transceiver = PS2_STATE_1_DATA_IN;
 | |
|         end
 | |
|     PS2_STATE_2_COMMAND_OUT:
 | |
|         begin
 | |
|             if((command_was_sent == 1'b1) || (error_communication_timed_out == 1'b1))
 | |
|                 ns_ps2_transceiver = PS2_STATE_3_END_TRANSFER;
 | |
|             else ns_ps2_transceiver = PS2_STATE_2_COMMAND_OUT;
 | |
|         end
 | |
|     PS2_STATE_3_END_TRANSFER:
 | |
|         begin
 | |
|             if(send_command == 1'b0) ns_ps2_transceiver = PS2_STATE_0_IDLE;
 | |
|             else if((ps2_data_reg == 1'b0) && (ps2_clk_posedge == 1'b1))
 | |
|                 ns_ps2_transceiver = PS2_STATE_4_END_DELAYED;
 | |
|             else ns_ps2_transceiver = PS2_STATE_3_END_TRANSFER;
 | |
|         end
 | |
|     PS2_STATE_4_END_DELAYED:
 | |
|         begin
 | |
|             if(received_data_en == 1'b1) begin
 | |
|                 if(send_command == 1'b0) ns_ps2_transceiver = PS2_STATE_0_IDLE;
 | |
|                 else                     ns_ps2_transceiver = PS2_STATE_3_END_TRANSFER;
 | |
|             end
 | |
|             else ns_ps2_transceiver = PS2_STATE_4_END_DELAYED;
 | |
|         end
 | |
| 
 | |
|     default:
 | |
|             ns_ps2_transceiver = PS2_STATE_0_IDLE;
 | |
|     endcase
 | |
|   end
 | |
| 
 | |
|   // --------------------------------------------------------------------
 | |
|   // Sequential logic
 | |
|   // --------------------------------------------------------------------
 | |
|   always @(posedge clk) begin
 | |
|     if(reset == 1'b1)     begin
 | |
|         last_ps2_clk    <= 1'b1;
 | |
|         ps2_clk_reg     <= 1'b1;
 | |
|         ps2_data_reg    <= 1'b1;
 | |
|     end
 | |
|     else begin
 | |
|         last_ps2_clk    <= ps2_clk_reg;
 | |
|         ps2_clk_reg     <= ps2_clk;
 | |
|         ps2_data_reg    <= ps2_dat;
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   always @(posedge clk) begin
 | |
|     if(reset == 1'b1) idle_counter <= 6'h00;
 | |
|     else if((s_ps2_transceiver == PS2_STATE_0_IDLE) && (idle_counter != 8'hFF))
 | |
|         idle_counter <= idle_counter + 6'h01;
 | |
|     else if (s_ps2_transceiver != PS2_STATE_0_IDLE)
 | |
|         idle_counter <= 6'h00;
 | |
|   end
 | |
| 
 | |
|   // --------------------------------------------------------------------
 | |
|   // Combinational logic
 | |
|   // --------------------------------------------------------------------
 | |
|   assign ps2_clk_posedge = ((ps2_clk_reg == 1'b1) && (last_ps2_clk == 1'b0)) ? 1'b1 : 1'b0;
 | |
|   assign ps2_clk_negedge = ((ps2_clk_reg == 1'b0) && (last_ps2_clk == 1'b1)) ? 1'b1 : 1'b0;
 | |
| 
 | |
|   assign start_receiving_data      = (s_ps2_transceiver == PS2_STATE_1_DATA_IN);
 | |
|   assign wait_for_incoming_data    = (s_ps2_transceiver == PS2_STATE_3_END_TRANSFER);
 | |
| 
 | |
|   // --------------------------------------------------------------------
 | |
|   // Internal Modules
 | |
|   // --------------------------------------------------------------------
 | |
|   ps2_mouse_cmdout mouse_cmdout (
 | |
|     .clk                           (clk),            // Inputs
 | |
|     .reset                         (reset),
 | |
|     .the_command                   (the_command),
 | |
|     .send_command                  (send_command),
 | |
|     .ps2_clk_posedge               (ps2_clk_posedge),
 | |
|     .ps2_clk_negedge               (ps2_clk_negedge),
 | |
|     .ps2_clk                       (ps2_clk),        // Bidirectionals
 | |
|     .ps2_dat                       (ps2_dat),
 | |
|     .command_was_sent              (command_was_sent),    // Outputs
 | |
|     .error_communication_timed_out (error_communication_timed_out)
 | |
|   );
 | |
| 
 | |
|   ps2_mouse_datain mouse_datain (
 | |
|     .clk                    (clk),        // Inputs
 | |
|     .reset                  (reset),
 | |
|     .wait_for_incoming_data (wait_for_incoming_data),
 | |
|     .start_receiving_data   (start_receiving_data),
 | |
|     .ps2_clk_posedge        (ps2_clk_posedge),
 | |
|     .ps2_clk_negedge        (ps2_clk_negedge),
 | |
|     .ps2_data               (ps2_data_reg),
 | |
|     .received_data          (received_data),   // Outputs
 | |
|     .received_data_en       (received_data_en)
 | |
|   );
 | |
| 
 | |
| endmodule
 | |
| 
 |