Add Quartus project
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Module: Altera_UP_PS2 *
|
||||
* Description: *
|
||||
* This module communicates with the PS2 core. *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
module PS2_Controller #(parameter INITIALIZE_MOUSE = 0) (
|
||||
// Inputs
|
||||
CLOCK_50,
|
||||
reset,
|
||||
|
||||
the_command,
|
||||
send_command,
|
||||
|
||||
// Bidirectionals
|
||||
PS2_CLK, // PS2 Clock
|
||||
PS2_DAT, // PS2 Data
|
||||
|
||||
// Outputs
|
||||
command_was_sent,
|
||||
error_communication_timed_out,
|
||||
|
||||
received_data,
|
||||
received_data_en // If 1 - new data has been received
|
||||
);
|
||||
|
||||
/*****************************************************************************
|
||||
* Parameter Declarations *
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Port Declarations *
|
||||
*****************************************************************************/
|
||||
// Inputs
|
||||
input CLOCK_50;
|
||||
input reset;
|
||||
|
||||
input [7:0] the_command;
|
||||
input send_command;
|
||||
|
||||
// Bidirectionals
|
||||
inout PS2_CLK;
|
||||
inout PS2_DAT;
|
||||
|
||||
// Outputs
|
||||
output command_was_sent;
|
||||
output error_communication_timed_out;
|
||||
|
||||
output [7:0] received_data;
|
||||
output received_data_en;
|
||||
|
||||
wire [7:0] the_command_w;
|
||||
wire send_command_w, command_was_sent_w, error_communication_timed_out_w;
|
||||
|
||||
generate
|
||||
if(INITIALIZE_MOUSE) begin
|
||||
assign the_command_w = init_done ? the_command : 8'hf4;
|
||||
assign send_command_w = init_done ? send_command : (!command_was_sent_w && !error_communication_timed_out_w);
|
||||
assign command_was_sent = init_done ? command_was_sent_w : 0;
|
||||
assign error_communication_timed_out = init_done ? error_communication_timed_out_w : 1;
|
||||
|
||||
reg init_done;
|
||||
|
||||
always @(posedge CLOCK_50)
|
||||
if(reset) init_done <= 0;
|
||||
else if(command_was_sent_w) init_done <= 1;
|
||||
|
||||
end else begin
|
||||
assign the_command_w = the_command;
|
||||
assign send_command_w = send_command;
|
||||
assign command_was_sent = command_was_sent_w;
|
||||
assign error_communication_timed_out = error_communication_timed_out_w;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
/*****************************************************************************
|
||||
* Constant Declarations *
|
||||
*****************************************************************************/
|
||||
// states
|
||||
localparam PS2_STATE_0_IDLE = 3'h0,
|
||||
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;
|
||||
|
||||
/*****************************************************************************
|
||||
* Internal wires and registers Declarations *
|
||||
*****************************************************************************/
|
||||
// Internal Wires
|
||||
wire ps2_clk_posedge;
|
||||
wire ps2_clk_negedge;
|
||||
|
||||
wire start_receiving_data;
|
||||
wire wait_for_incoming_data;
|
||||
|
||||
// Internal Registers
|
||||
reg [7:0] idle_counter;
|
||||
|
||||
reg ps2_clk_reg;
|
||||
reg ps2_data_reg;
|
||||
reg last_ps2_clk;
|
||||
|
||||
// State Machine Registers
|
||||
reg [2:0] ns_ps2_transceiver;
|
||||
reg [2:0] s_ps2_transceiver;
|
||||
|
||||
/*****************************************************************************
|
||||
* Finite State Machine(s) *
|
||||
*****************************************************************************/
|
||||
|
||||
always @(posedge CLOCK_50)
|
||||
begin
|
||||
if (reset == 1'b1)
|
||||
s_ps2_transceiver <= PS2_STATE_0_IDLE;
|
||||
else
|
||||
s_ps2_transceiver <= ns_ps2_transceiver;
|
||||
end
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
// Defaults
|
||||
ns_ps2_transceiver = PS2_STATE_0_IDLE;
|
||||
|
||||
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)*/)
|
||||
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 CLOCK_50)
|
||||
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 CLOCK_50)
|
||||
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 *
|
||||
*****************************************************************************/
|
||||
|
||||
Altera_UP_PS2_Data_In PS2_Data_In (
|
||||
// Inputs
|
||||
.clk (CLOCK_50),
|
||||
.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),
|
||||
|
||||
// Bidirectionals
|
||||
|
||||
// Outputs
|
||||
.received_data (received_data),
|
||||
.received_data_en (received_data_en)
|
||||
);
|
||||
|
||||
Altera_UP_PS2_Command_Out PS2_Command_Out (
|
||||
// Inputs
|
||||
.clk (CLOCK_50),
|
||||
.reset (reset),
|
||||
|
||||
.the_command (the_command_w),
|
||||
.send_command (send_command_w),
|
||||
|
||||
.ps2_clk_posedge (ps2_clk_posedge),
|
||||
.ps2_clk_negedge (ps2_clk_negedge),
|
||||
|
||||
// Bidirectionals
|
||||
.PS2_CLK (PS2_CLK),
|
||||
.PS2_DAT (PS2_DAT),
|
||||
|
||||
// Outputs
|
||||
.command_was_sent (command_was_sent_w),
|
||||
.error_communication_timed_out (error_communication_timed_out_w)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
Reference in New Issue
Block a user