module keyboard(
input logic clk,
input logic ps2d,
input logic ps2c,
input logic ack,
output logic [15:0] dout
);
localparam [1:0]
IDLE = 2'b00,
READ = 2'b01,
END = 2'b10;
logic [7:0] filter;
logic rx_done_tick;
logic [3:0] count;
logic [1:0] state;
logic [1:0] c;
logic fall_edge;
logic [10:0] char;
logic status;
//filter falling edge ps2c
always_ff @(posedge clk)
begin
filter <= {ps2c,filter[7:1]};
if (filter == 8'b11111111)
c<= {1'b1,c[1]}; //c[0] is past, c[1] is now.
else if (filter == 8'b00000000)
c<={1'b0,c[1]};
end
assign fall_edge = c[0] & ~c[1]; //falling edge..
//FSM
always_ff @ (posedge clk)
begin
rx_done_tick <= 1'b0;
case (state)
IDLE:
if(fall_edge & ~status)
begin
char <= {ps2d,char[10:1]};
count <= 4'd9;
state <= READ;
end
READ:
if(fall_edge)
begin
char <= {ps2d,char[10:1]};
if(count == 0)
state <= END;
else
count <= count -1;
end
END:
begin
rx_done_tick <= 1'b1;
state <= IDLE;
end
endcase
end
always_ff @ (posedge clk)
if(rx_done_tick)
status<=1'b1;
else if (status ==1 & ack == 1)
status<=1'b0;
always_comb
if (ack ==1'b1)
dout = 16'(char[8:1]);// assign scan code
else
dout = 16'(status);
initial
begin
status =0;
state = IDLE;
end
endmodule