§ TOP-схема

Тактировать на 25 мгц, но в целом, можно на любой близкой частоте.
Эта версия отличается от предыдущей тем, что здесь учтена проверка бита четности, а также истечение таймаута для предотвращения зависания в статусе чтения, улучшена установка done на негативном фронте.
1wire [ 7:0] ps_data;
2wire        ps_done;
3
4ps2 Keyb
5(
6    .clock      (clock_25),
7    .ps_clock   (PS2_CLK),
8    .ps_data    (PS2_DAT),
9    .done       (ps_done),
10    .data       (ps_data)
11);
12
13// Пример имплементации
14reg [7:0] new_data;
15always @(posedge clock_25)
16    if (ps_done)
17        new_data <= ps_data;

§ Код ps2.v

1module ps2
2(
3    input clock,
4    input ps_clock,
5    input ps_data,
6
7    output reg       done,
8    output reg [7:0] data
9);
10
11reg         kbusy   = 1'b0;
12reg         kdone   = 1'b0;
13reg [1:0]   klatch  = 2'b00;
14reg [3:0]   kcount  = 1'b0;
15reg [9:0]   kin     = 1'b0;
16reg [19:0]  kout    = 1'b0;
17
18initial begin data = 8'h00; done = 1'b0; end
19
20// Для повышения точности
21always @(negedge clock) done <= kdone;
22
23// Основная логика работы контроллера
24always @(posedge clock) begin
25
26    kdone <= 1'b0;
27
28    // Процесс приема сигнала
29    if (kbusy) begin
30
31        // Позитивный фронт
32        if (klatch == 2'b01) begin
33
34            // Завершающий такт
35            if (kcount == 4'hA) begin
36
37                data    <= kin[8:1];
38                kbusy   <= 1'b0;
39                kdone   <= ^kin[9:1]; // =1 Если четность совпадает
40
41            end
42
43            kcount  <= kcount + 1'b1;
44            kin     <= {ps_data, kin[9:1]};
45
46        end
47
48        // Считать "зависший процесс"
49        kout <= ps_clock ? kout + 1 : 1'b0;
50
51        // И если прошло более 20 мс, то перевести в состояние ожидания
52        if (kout > 25000*20) kbusy <= 1'b0;
53
54    end else begin
55
56        // Обнаружен негативный фронт \__
57        if (klatch == 2'b10) begin
58
59            kbusy   <= 1'b1; // Активировать прием данных
60            kcount  <= 1'b0;
61            kout    <= 1'b0;
62
63        end
64
65    end
66
67    klatch <= {klatch[0], ps_clock};
68
69end
70
71endmodule