1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-02-06 16:14:42 +00:00
Files
mist-devel.mist-board/cores/bbc/rtl/ps2_intf.v
2015-09-29 21:05:29 +02:00

180 lines
5.1 KiB
Verilog

`timescale 1 ns / 1 ns // timescale for following modules
// ZX Spectrum for Altera DE1
//
// Copyright (c) 2009-2011 Mike Stirling
//
// All rights reserved
//
// Redistribution and use in source and synthezised forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in synthesized form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software without
// specific prior written agreement from the author.
//
// * License is granted for non-commercial use only. A fee may not be charged
// for redistributions as source code or in synthesized/hardware form without
// specific prior written agreement from the author.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// PS/2 interface (input only)
// Based loosely on ps2_ctrl.vhd (c) ALSE. http://www.alse-fr.com
module ps2_intf (
input CLK,
input nRESET,
input PS2_CLK,
input PS2_DATA,
output reg [7:0] DATA,
output reg VALID,
output reg ERROR
);
parameter filter_length = 8;
reg [filter_length - 1:0] clk_filter;
reg ps2_clk_in;
reg ps2_dat_in;
// Goes high when a clock falling edge is detected
reg clk_edge;
reg [3:0] bit_count;
reg [8:0] shiftreg;
reg parity;
// Register input signals
always @(posedge CLK) begin
if (nRESET === 1'b 0) begin
ps2_clk_in <= 1'b 1;
ps2_dat_in <= 1'b 1;
clk_filter <= {(filter_length - 1 - 0 + 1){1'b 1}};
clk_edge <= 1'b 0;
end else begin
// Register inputs (and filter clock)
ps2_dat_in <= PS2_DATA;
clk_filter <= {PS2_CLK, clk_filter[7:1]};
clk_edge <= 1'b 0;
if (clk_filter === 1'b 1) begin
// Filtered clock is high
ps2_clk_in <= 1'b 1;
end else if (clk_filter === 1'b 0 ) begin
// Filter clock is low, check for edge
if (ps2_clk_in === 1'b 1) begin
clk_edge <= 1'b 1;
end
ps2_clk_in <= 1'b 0;
end
end
end
// Shift in keyboard data
always @(posedge CLK) begin
if (nRESET === 1'b 0) begin
bit_count <= 'd0;
shiftreg <= 'd0;
parity <= 1'b0;
DATA <= 'd0;
VALID <= 1'b 0;
ERROR <= 1'b 0;
end else begin
// Clear flags
VALID <= 1'b 0;
ERROR <= 1'b 0;
if (clk_edge === 1'b 1) begin
// We have a new bit from the keyboard for processing
if (bit_count === 0) begin
// Idle state, check for start bit (0) only and don't
// start counting bits until we get it
parity <= 1'b 0;
if (ps2_dat_in === 1'b 0) begin
// This is a start bit
bit_count <= bit_count + 'd1;
end
// Running. 8-bit data comes in LSb first followed by
// a single stop bit (1)
end else begin
if (bit_count < 10) begin
// Shift in data and parity (9 bits)
bit_count <= bit_count + 1;
shiftreg <= {ps2_dat_in, shiftreg[8:1]};
parity <= parity ^ ps2_dat_in;
// Calculate parity
end else if (ps2_dat_in === 1'b 1 ) begin
// Valid stop bit received
bit_count <= 'd0;
// back to idle
if (parity === 1'b 1) begin
// Parity correct, submit data to host
DATA <= shiftreg[7:0];
VALID <= 1'b 1;
// Error
end else begin
ERROR <= 1'b 1;
end
end else begin // Invalid stop bit
bit_count <= 'd0;
// back to idle
ERROR <= 1'b 1;
end
end
end
end
end
endmodule // module ps2_intf