§ Тактирование
Такты приходят от клавиатуры. Модуль их только принимает.
§ TOP-модуль
Модуль можно тактировать на 25 Мгц, но можно и на более низких частотах. Даже до 1 Мгц.always @(posedge clock_25) if (keyb_ready) led <= {led[15:0], keyb_data}; // Модуль клавиатуры keyboard KeyboardPS2 ( .clock_25 (clock_25), .PS2_CLK (PS2_CLK), .PS2_DAT (PS2_DAT), .keyb_ready (keyb_ready), .keyb_data (keyb_data) );
§ Модуль keyboard.v
/* * Модуль приема данных от клавиатуры PS/2 * При keyb_ready=1, на позитивном фронте clock_25 будут доступен keyb_data */ module keyboard ( input wire clock_25, inout wire PS2_CLK, inout wire PS2_DAT, output reg keyb_ready, output reg [7:0] keyb_data ); // --------------------------------------------------------------------- // ОБЪЯВЛЕНИЯ // --------------------------------------------------------------------- reg state; reg [ 9:0] data; reg [ 3:0] cnt; reg [ 1:0] k; // --------------------------------------------------------------------- // ОСНОВНАЯ ЛОГИКА // --------------------------------------------------------------------- always @(negedge clock_25) begin keyb_ready <= 1'b0; case (state) // Статус ожидания старта 0: if (k == 2'b10) begin state <= 1'b1; cnt <= 0; end // На позитивном фронте CLK 1: if (k == 2'b01) begin // 1 9..2 10 11 // Start | 8 bit | Parity | Stop if (cnt == 10) begin // В data[9] => Parity (проверить четность) // В data[0] => Start (равен 0) state <= 1'b0; keyb_ready <= (PS2_DAT == 1'b1) && (data[0] == 1'b0); keyb_data <= data[8:1]; end // LSB первым идет data <= {PS2_DAT, data[9:1]}; cnt <= cnt + 1; end endcase k <= {k[0], PS2_CLK}; end endmodule