Estoy intentando que funcione un diseño de Verilog para interactuar con un teclado PS / 2, pero tengo problemas muy extraños. Tengo un bloque siempre bastante simple que controla todo:
always@(negedge PS2_CLOCK) begin
if(rst == 0) begin
state <= READY;
index <= 0;
keycode <= 0;
data <= 0;
is_pressed <= 0;
end
else begin
case (state)
READY: begin
state <= GRAB;
is_pressed <= 0;
end
GRAB: begin
if(index == 7) begin
data <= (data >> 1) | (PS2_DATA << 7);
index <= 0;
state <= PARITY;
end
else begin
data <= (data >> 1) | (PS2_DATA << 7);
index <= index + 3'b1;
end
end
PARITY: begin
state <= DONE;
end
DONE: begin
is_pressed <= 1;
state <= READY;
keycode <= data;
data <= 0;
index <= 0;
end
endcase
end
end
Como puede ver, esto se ejecuta en función del margen del reloj PS / 2, pero no estoy seguro de que sea una buena idea. De vez en cuando, cuando presiono un botón en el teclado, no recibo los datos correctamente y creo que es debido a la incertidumbre en la señal del reloj. Aquí hay dos ejecuciones del código cuando se presiona un botón:
El primero es de una ejecución correcta de la máquina de estado, mientras que el segundo tiene una clara interrupción en la señal del reloj. En este caso, no fue muy dañino, pero si ocurre cerca del final de la transmisión de datos, a menudo hace que mi máquina salte un estado y se desincronice. Cualquier consejo sería muy apreciado.