Fixed video, kbd and buzzer
This commit is contained in:
+110
@@ -0,0 +1,110 @@
|
||||
//============================================================================
|
||||
// PS/2 keyboard scan-code reader
|
||||
//
|
||||
// Copyright (C) 2014-2016 Goran Devic
|
||||
//
|
||||
// This program is free software; 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 2 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//============================================================================
|
||||
module ps2_keyboard
|
||||
(
|
||||
input wire clk,
|
||||
input wire nreset, // Active low reset
|
||||
input wire PS2_CLK, // PS/2 keyboard clock line
|
||||
input wire PS2_DAT, // PS/2 keyboard data line
|
||||
|
||||
output wire [7:0] scan_code,// Completed keyboard scan code
|
||||
output reg scan_code_ready, // Active for 1 clock: scan code is ready
|
||||
output reg scan_code_error // Error receiving keyboard data
|
||||
);
|
||||
|
||||
reg [7:0] clk_filter;
|
||||
reg ps2_clk_in;
|
||||
|
||||
reg clk_edge;
|
||||
reg [3:0] bit_count;
|
||||
|
||||
// Shift register contains all the bits that are read so far; scan_code simply
|
||||
// mirrors it and becomes valid only when "scan_code_ready" is set
|
||||
reg [8:0] shiftreg;
|
||||
assign scan_code = shiftreg[7:0];
|
||||
|
||||
// Compute parity on the fly; we only need it after the last bit is stored
|
||||
wire parity;
|
||||
assign parity = ^shiftreg[8:0];
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Filter the PS/2 clock signal since it might have a noise (false '1')
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
always @(posedge clk or negedge nreset)
|
||||
begin
|
||||
if (!nreset) begin
|
||||
ps2_clk_in <= 1;
|
||||
clk_filter <= 8'b1;
|
||||
clk_edge <= 0;
|
||||
end
|
||||
else begin
|
||||
// Filter in a new keyboard clock sample
|
||||
clk_filter <= { PS2_CLK, clk_filter[7:1] };
|
||||
clk_edge <= 0;
|
||||
|
||||
if (clk_filter==8'b1)
|
||||
ps2_clk_in <= 1;
|
||||
else if (clk_filter==8'b0) begin
|
||||
// Filter clock is low, check for edge
|
||||
if (ps2_clk_in==1)
|
||||
clk_edge <= 1;
|
||||
ps2_clk_in <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// State machine to process bits of PS/2 data
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
always @(posedge clk or negedge nreset)
|
||||
begin
|
||||
if (!nreset) begin
|
||||
bit_count <= '0;
|
||||
shiftreg <= '0;
|
||||
scan_code_ready <= 0;
|
||||
scan_code_error <= 0;
|
||||
end
|
||||
else begin
|
||||
scan_code_ready <= 0;
|
||||
scan_code_error <= 0;
|
||||
// We have a new valid clocked bit from the keyboard
|
||||
if (clk_edge==1) begin
|
||||
// Start condition, the bit count is 0
|
||||
if (bit_count==0 && PS2_DAT==0)
|
||||
bit_count <= bit_count + 4'h1;
|
||||
else begin
|
||||
// Collecting up to 8 data bits and a parity bit
|
||||
if (bit_count < 10) begin
|
||||
bit_count <= bit_count + 4'h1;
|
||||
shiftreg <= { PS2_DAT, shiftreg[8:1] };
|
||||
end
|
||||
else
|
||||
// Finalize: both the calculated parity and the stop bits should be '1'
|
||||
begin
|
||||
bit_count <= '0;
|
||||
scan_code_ready <= { PS2_DAT, parity} == 2'b11;
|
||||
scan_code_error <= { PS2_DAT, parity} != 2'b11;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user