127 lines
3.0 KiB
Verilog
Executable File
127 lines
3.0 KiB
Verilog
Executable File
module KeyboardDecoder(
|
|
output reg [511:0] key_down,
|
|
output wire [8:0] last_change,
|
|
output reg key_valid,
|
|
inout wire PS2_DATA,
|
|
inout wire PS2_CLK,
|
|
input wire rst,
|
|
input wire clk
|
|
);
|
|
|
|
parameter [1:0] INIT = 2'b00;
|
|
parameter [1:0] WAIT_FOR_SIGNAL = 2'b01;
|
|
parameter [1:0] GET_SIGNAL_DOWN = 2'b10;
|
|
parameter [1:0] WAIT_RELEASE = 2'b11;
|
|
|
|
parameter [7:0] IS_INIT = 8'hAA;
|
|
parameter [7:0] IS_EXTEND = 8'hE0;
|
|
parameter [7:0] IS_BREAK = 8'hF0;
|
|
|
|
reg [9:0] key; // key = {been_extend, been_break, key_in}
|
|
reg [1:0] state;
|
|
reg been_ready, been_extend, been_break;
|
|
|
|
wire [7:0] key_in;
|
|
wire is_extend;
|
|
wire is_break;
|
|
wire valid;
|
|
wire err;
|
|
|
|
wire [511:0] key_decode = 1 << last_change;
|
|
assign last_change = {key[9], key[7:0]};
|
|
|
|
KeyboardCtrl_0 inst (
|
|
.key_in(key_in),
|
|
.is_extend(is_extend),
|
|
.is_break(is_break),
|
|
.valid(valid),
|
|
.err(err),
|
|
.PS2_DATA(PS2_DATA),
|
|
.PS2_CLK(PS2_CLK),
|
|
.rst(rst),
|
|
.clk(clk)
|
|
);
|
|
|
|
OnePulse op (
|
|
.signal_single_pulse(pulse_been_ready),
|
|
.signal(been_ready),
|
|
.clock(clk)
|
|
);
|
|
|
|
always @ (posedge clk, posedge rst) begin
|
|
if (rst) begin
|
|
state <= INIT;
|
|
been_ready <= 1'b0;
|
|
been_extend <= 1'b0;
|
|
been_break <= 1'b0;
|
|
key <= 10'b0_0_0000_0000;
|
|
end else begin
|
|
state <= state;
|
|
been_ready <= been_ready;
|
|
been_extend <= (is_extend) ? 1'b1 : been_extend;
|
|
been_break <= (is_break ) ? 1'b1 : been_break;
|
|
key <= key;
|
|
case (state)
|
|
INIT : begin
|
|
if (key_in == IS_INIT) begin
|
|
state <= WAIT_FOR_SIGNAL;
|
|
been_ready <= 1'b0;
|
|
been_extend <= 1'b0;
|
|
been_break <= 1'b0;
|
|
key <= 10'b0_0_0000_0000;
|
|
end else begin
|
|
state <= INIT;
|
|
end
|
|
end
|
|
WAIT_FOR_SIGNAL : begin
|
|
if (valid == 0) begin
|
|
state <= WAIT_FOR_SIGNAL;
|
|
been_ready <= 1'b0;
|
|
end else begin
|
|
state <= GET_SIGNAL_DOWN;
|
|
end
|
|
end
|
|
GET_SIGNAL_DOWN : begin
|
|
state <= WAIT_RELEASE;
|
|
key <= {been_extend, been_break, key_in};
|
|
been_ready <= 1'b1;
|
|
end
|
|
WAIT_RELEASE : begin
|
|
if (valid == 1) begin
|
|
state <= WAIT_RELEASE;
|
|
end else begin
|
|
state <= WAIT_FOR_SIGNAL;
|
|
been_extend <= 1'b0;
|
|
been_break <= 1'b0;
|
|
end
|
|
end
|
|
default : begin
|
|
state <= INIT;
|
|
been_ready <= 1'b0;
|
|
been_extend <= 1'b0;
|
|
been_break <= 1'b0;
|
|
key <= 10'b0_0_0000_0000;
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
always @ (posedge clk, posedge rst) begin
|
|
if (rst) begin
|
|
key_valid <= 1'b0;
|
|
key_down <= 511'b0;
|
|
end else if (key_decode[last_change] && pulse_been_ready) begin
|
|
key_valid <= 1'b1;
|
|
if (key[8] == 0) begin
|
|
key_down <= key_down | key_decode;
|
|
end else begin
|
|
key_down <= key_down & (~key_decode);
|
|
end
|
|
end else begin
|
|
key_valid <= 1'b0;
|
|
key_down <= key_down;
|
|
end
|
|
end
|
|
|
|
endmodule
|