las mejores prácticas de CPLD para restablecer un contador

2

Mi solicitud tiene una sección estándar de conteo de fallas hasta un número determinado y luego reiniciar el contador. Mi amigo experimentado me dice que al usar fichas reales, es común incrementar el contador en el flanco ascendente del reloj y restablecer el contador en el borde descendente. De esa manera, el diseñador tiene mucho tiempo para hacer lo que debe hacerse antes de que llegue el próximo reloj.

Pero nunca ha usado un CPLD y me pregunto si esto cambia las reglas. O si su información es técnicamente razonable pero no es prácticamente necesaria.

Mi diseño tiene algo como

always @(posedge clock) begin (increment the clock) end
always @(negedge clock) begin (reset the counter conditionally) end

No estoy entrenado en ingeniería eléctrica, solo leo y me meto. Pero no puedo dejar que descanse cuando siento que no tengo un cierto entendimiento (nivel n00b) de lo que está pasando.

Acabo de leer un ejemplo de un curso universitario en el que al instructor no le importó cuándo se restableció el contador. Su diseño era algo así como:

always @(posedge clock) begin
    counter = counter + 1;
    if (counter == some_number) counter = 0;
    end

Esto me lleva a creer que estoy sobre ingeniería, el instructor está instruyendo no está construyendo una aplicación industrial, o el proceso de síntesis maneja esas cosas.

Por supuesto que podría probarlo en el simulador o introducirlo en el CPLD. Eventualmente, esto conducirá una máquina poderosa y tiene que funcionar cada vez. No puedo tener un caso extremo donde la máquina se comporte mal.

EDITAR - más contexto. Si bien puede que no importe con respecto a la respuesta, estoy contando los pulsos generados por un codificador conectado a un eje giratorio. Tengo que contarlos a todos, y no puedo perder ninguno.

EDIT 2: ejemplo de un bucle que incrementa un contador, luego, en alguna condición, lo cambia.

module slow_count(
    input clk,
    output reg [3:0] count
    );

    reg[19:0] snooze = 0;
    always @(posedge clk) begin
        snooze = snooze + 1;            // Set the counter
        if (snooze == 1000000) begin
            snooze = 0;             // And change it here
            count = count + 1;
            if (count == 10) count = 0;
            end
        end

endmodule
    
pregunta Tony Ennis

3 respuestas

3

Parece que no tienes una señal de restablecimiento externa para responder, solo quieres contar un número y luego ir a cero como el siguiente paso. Podría considerar esto como un contador mod n , donde n es uno más que el conteo máximo en su contador.

Así que no estoy seguro de lo que quieres decir con "perder una señal" mientras realizas el reinicio. Si tuviera un contador decimal de 3 dígitos y pasara de 999 a 000, no lo consideraría como "perder una señal", solo estaría contando hasta el siguiente valor en aritmética mod-1000.

Así que si lo haces

always @(posedge clock) begin
    if (counter == some_number) begin
         counter <= 0;
    end
    else begin
        counter <= counter + 1;
    end
end

Tendrás un contador que cuenta continuamente en mod- some_number+1 arithmetic. Alternativamente, podrías decir que cuenta para some_number , luego se restablece a cero sin "perder" un pulso de reloj.

Si some_number+1 es una potencia de 2, ni siquiera necesita la condición de reinicio en su código. Por ejemplo, para un contador mod-16, solo puede usar un contador de 4 bits, y la lógica sintetizada contará de manera continua y repetida de 0 a 15.

    
respondido por el The Photon
2

Si no hay razón para hacer lo contrario, siempre borro el contador en el siguiente borde positivo, asumiendo que el contador es un borde positivo activado. Esto mantiene constante el tiempo en cada valor, lo que puede ser importante si el contador comparte una señal de reloj con y controla otros bloques, y especialmente los divisores de frecuencia. Como siempre, las operaciones síncronas son tus amigas. Su ejemplo de universidad es una buena práctica en mi opinión.

    
respondido por el Matt Young
1

Si no necesita restablecer el contador de forma asíncrona, entonces el contador simplemente debe determinar en cada ciclo de reloj cuál debe ser el siguiente valor de reloj, de modo que todo se ejecute fuera del mismo borde del reloj. Si necesita reiniciar el contador de forma asíncrona, hay una variedad de enfoques que se pueden usar según lo que se sabe sobre el tiempo de la entrada de reinicio (sobre todo, si existe alguna posibilidad de que la señal de reinicio se libere cerca de un contador). borde del reloj, y / o cualquier posibilidad de pulso de restablecimiento "runt").

La forma más robusta de reiniciar el contador de forma asincrónica es tener una secuencia de tres flip flops que son operados por el reloj principal, y el primero se reinicia de forma asíncrona mediante la entrada de reinicio maestro. La entrada de datos al primer flop debe ser alta cuando su salida es alta y la segunda es alta o la tercera es baja, o cuando los tres flops son bajos. El contador en sí no debe reiniciarse de forma asíncrona, sino que debe cargarse con un valor inicial siempre que el tercer flip flop sea bajo. Las salidas del contador deben ser asincrónicamente "AND" con el "y" de los tres flip flops antes de conducir los circuitos descendentes.

Al utilizar este enfoque, cualquier reinicio de longitud adecuada hará que las salidas se reduzcan de forma asíncrona. Un pulso de reinicio de funcionamiento puede hacer que las salidas de conteo del circuito general se vuelvan momentáneamente inestables, pero se restablecerán limpiamente o, dentro de dos ciclos, volverán a la secuencia de conteo original. Como se describe, habrá pocos ciclos de retardo entre la liberación del restablecimiento y la observación del primer conteo; dicho retardo se puede eliminar agregando una lógica adicional entre el contador y los circuitos alimentados por el mismo, y haciendo que el contador cargue un valor distinto de cero. Efectivamente, los primeros recuentos después de un restablecimiento serían manejados por los flip flops en lugar del contador. Un pulso de reinicio de ejecución puede hacer que esos primeros recuentos aparezcan de forma extraña, pero los recuentos después de ellos estarían bien.

    
respondido por el supercat

Lea otras preguntas en las etiquetas