¿Se debe usar el reloj de un teclado PS / 2 en un Verilog siempre bloqueado?

0

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.

    
pregunta user3211355

1 respuesta

1

No siempre es recomendable bloquear en un reloj relativamente lento en un chip lógico relativamente rápido. Dependiendo de cómo funcionó la herramienta de síntesis, puede usar uno de los pocos árboles de reloj dedicados en el chip o simplemente una línea de IO regular. Es posible que un árbol de reloj dedicado no admita una baja frecuencia y que la IO normal se desvíe incorrectamente. Sospecho que uno de los siguientes:

Problema de sincronización entre dominios

Si se está conectando con una lógica más rápida, necesitará algo de FIFO para cruzar los dominios del reloj o puede perder datos en la transferencia. Por lo general, esto ocurre cuando se pasa de más rápido a más lento (por ejemplo, desbordamiento de FIFO), pero en la silicona real, cruzar un dominio de reloj es complicado

configuración y tiempos de espera

si su LUT o segmento se está ejecutando en un reloj lento, es posible que el presionar el botón que causa la falta de sincronización se deba a un retraso en la propagación. Es poco probable, pero puede valer la pena ver la frecuencia del reloj PS / 2 en su herramienta de cierre de tiempo.

mi solución

Bloquearía el reloj usado en el resto de tu sistema. Use un registro de 2 bits y un cambio de bits en el reloj PS / 2 para hacer un detector de bordes. Entonces controlas tu máquina de estados en el flanco descendente (2'b10). Al usar el reloj rápido, incluso si tiene un retraso de 1 ciclo antes de leer el bit de datos, todavía tiene cientos de ciclos para tomar una muestra.

    
respondido por el Bageletas

Lea otras preguntas en las etiquetas