§ TOP-схема

Тактировать на 25 мгц, но в целом, можно на любой близкой частоте.
Эта версия отличается от предыдущей тем, что здесь учтена проверка бита четности, а также истечение таймаута для предотвращения зависания в статусе чтения, улучшена установка done на негативном фронте.
wire [ 7:0] ps_data;
wire        ps_done;

ps2 Keyb
(
    .clock      (clock_25),
    .ps_clock   (PS2_CLK),
    .ps_data    (PS2_DAT),
    .done       (ps_done),
    .data       (ps_data)
);

// Пример имплементации
reg [7:0] new_data;
always @(posedge clock_25)
    if (ps_done)
        new_data <= ps_data;

§ Код ps2.v

module ps2
(
    input clock,
    input ps_clock,
    input ps_data,

    output reg       done,
    output reg [7:0] data
);

reg         kbusy   = 1'b0;
reg         kdone   = 1'b0;
reg [1:0]   klatch  = 2'b00;
reg [3:0]   kcount  = 1'b0;
reg [9:0]   kin     = 1'b0;
reg [19:0]  kout    = 1'b0;

initial begin data = 8'h00; done = 1'b0; end

// Для повышения точности
always @(negedge clock) done <= kdone;

// Основная логика работы контроллера
always @(posedge clock) begin

    kdone <= 1'b0;

    // Процесс приема сигнала
    if (kbusy) begin

        // Позитивный фронт
        if (klatch == 2'b01) begin

            // Завершающий такт
            if (kcount == 4'hA) begin

                data    <= kin[8:1];
                kbusy   <= 1'b0;
                kdone   <= ^kin[9:1]; // =1 Если четность совпадает

            end

            kcount  <= kcount + 1'b1;
            kin     <= {ps_data, kin[9:1]};

        end

        // Считать "зависший процесс"
        kout <= ps_clock ? kout + 1 : 1'b0;

        // И если прошло более 20 мс, то перевести в состояние ожидания
        if (kout > 25000*20) kbusy <= 1'b0;

    end else begin

        // Обнаружен негативный фронт \__
        if (klatch == 2'b10) begin

            kbusy   <= 1'b1; // Активировать прием данных
            kcount  <= 1'b0;
            kout    <= 1'b0;

        end

    end

    klatch <= {klatch[0], ps_clock};

end

endmodule