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