2021-11-26 17:45:57 +08:00

136 lines
3.9 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, next_key; // key = {been_extend, been_break, key_in}
reg [1:0] state, next_state;
reg been_ready, been_extend, been_break;
reg next_been_ready, next_been_extend, next_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 <= next_state;
been_ready <= next_been_ready;
been_extend <= next_been_extend;
been_break <= next_been_break;
key <= next_key;
end
end
always @ (*) begin
case (state)
INIT: next_state = (key_in == IS_INIT) ? WAIT_FOR_SIGNAL : INIT;
WAIT_FOR_SIGNAL: next_state = (valid == 1'b0) ? WAIT_FOR_SIGNAL : GET_SIGNAL_DOWN;
GET_SIGNAL_DOWN: next_state = WAIT_RELEASE;
WAIT_RELEASE: next_state = (valid == 1'b1) ? WAIT_RELEASE : WAIT_FOR_SIGNAL;
default: next_state = INIT;
endcase
end
always @ (*) begin
next_been_ready = been_ready;
case (state)
INIT: next_been_ready = (key_in == IS_INIT) ? 1'b0 : next_been_ready;
WAIT_FOR_SIGNAL: next_been_ready = (valid == 1'b0) ? 1'b0 : next_been_ready;
GET_SIGNAL_DOWN: next_been_ready = 1'b1;
WAIT_RELEASE: next_been_ready = next_been_ready;
default: next_been_ready = 1'b0;
endcase
end
always @ (*) begin
next_been_extend = (is_extend) ? 1'b1 : been_extend;
case (state)
INIT: next_been_extend = (key_in == IS_INIT) ? 1'b0 : next_been_extend;
WAIT_FOR_SIGNAL: next_been_extend = next_been_extend;
GET_SIGNAL_DOWN: next_been_extend = next_been_extend;
WAIT_RELEASE: next_been_extend = (valid == 1'b1) ? next_been_extend : 1'b0;
default: next_been_extend = 1'b0;
endcase
end
always @ (*) begin
next_been_break = (is_break) ? 1'b1 : been_break;
case (state)
INIT: next_been_break = (key_in == IS_INIT) ? 1'b0 : next_been_break;
WAIT_FOR_SIGNAL: next_been_break = next_been_break;
GET_SIGNAL_DOWN: next_been_break = next_been_break;
WAIT_RELEASE: next_been_break = (valid == 1'b1) ? next_been_break : 1'b0;
default: next_been_break = 1'b0;
endcase
end
always @ (*) begin
next_key = key;
case (state)
INIT: next_key = (key_in == IS_INIT) ? 10'b0_0_0000_0000 : next_key;
WAIT_FOR_SIGNAL: next_key = next_key;
GET_SIGNAL_DOWN: next_key = {been_extend, been_break, key_in};
WAIT_RELEASE: next_key = next_key;
default: next_key = 10'b0_0_0000_0000;
endcase
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