Skip to content

4: Keyboard


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