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