4 votos

CPLD (a veces) no incrementa el contador de

Tengo este simple programa que se ejecuta en el Atera EPM240 que a veces, no haciendo el incremento del contador.

reg trigger_state;
reg [7:0] trigger_count;

always @ (posedge clk)
begin
    if (trigger != trigger_state) begin
      trigger_state <= !trigger_state;
      trigger_count <= trigger_count + 1;
    end
end

clk está ejecutando en 50MHz, la señal de disparo en la imagen a 1-2kHz.

enter image description here En la imagen (trigger=6, trigger_state=4, trigger_count[1]=1, trigger_count[0]=2)

Como se puede ver trigger_state siempre sigue a la señal de entrada (trigger), pero el contador (2) a veces no se incrementa.

¿Qué podría explicar este tipo de comportamiento?

9voto

GSerg Puntos 33571

Es el trigger de entrada completamente asíncrona para el reloj de 50MHz? Si es así, probablemente viola la instalación y mantener los requisitos de tiempo de vez en cuando. Usted necesita para sincronizar el reloj a través de al menos dos FFs antes de utilizarla en la toma de decisiones.

Puedo oír diciendo, "Pero sólo se utiliza en una if declaración. Si el trigger_state se actualiza, no se que garantizan trigger_count se actualiza, también?"

La respuesta es "no".

trigger_state y trigger_count representan un total de nueve FFs, y cada uno de ellos tiene su propia combinatoria lógica para determinar cuál es su siguiente estado será. Cada uno toma trigger como una entrada, y cada uno de ellos tomar una decisión independiente sobre lo que el valor de trigger es. Si usted viola la instalación/tiempo de retención de los requisitos, usted no puede garantizar que dichas decisiones independientes serán consistentes, que conduce a la conducta que observe.

Tenga en cuenta que esto no tiene nada que ver con la metaestabilidad, aunque la sincronización asíncrona entradas mitiga ese problema, también.

7voto

yeyo123321 Puntos 8

Lo primero de todo:
El gatillo está llegando en un sincronizada con el reloj. Primero debe sincronizar antes de que usted puede utilizar con seguridad. El código es:

reg sync_trigger,safe_trigger;
always @(posedge clk)
begin
    sync_trigger <= trigger;
    safe_trigger <= sync_trigger;
end

El comportamiento de tu estás viendo es porque el hardware de más tener este aspecto:

if (trigger != trigger_state) 
  trigger_state <= !trigger_state;

if (trigger != trigger_state) 
  trigger_count <= trigger_count + 1;

Cuando el gatillo es un síncrono puede tener ese si es verdadero y el otro es falso. Así, uno actúa y el otro no. De hecho, es implementado por cada uno de los BITS de su contador, por lo que algunos de bits pueden incrementar y otros no.

Post pensamiento:
Su gatillo debe ser más lento que el reloj de lo contrario se perderá desencadenantes!

4voto

Tom Carpenter Puntos 7192

El problema es más probable meta-estabilidad causados por el uso de una señal asincrónica (su entrada trigger) para el control de su contador.

Cuando el ingreso de cualquier señal en, usted necesita para asegurarse de que está sincronizada con la señal de reloj a través de múltiples registrar synchroniser de la cadena. Algo así como:

reg [1:0] triggerSync;
always @ (posedge clk) begin
    triggerSync <= {triggerSync[0],trigger}
end

A continuación, utilice triggerSync[1] en su código. El primer registro triggerSync[0] se sincroniza la señal, pero puede ir metaestable si la entrada cambia a medida que el reloj está cambiando (el programa de instalación/a sostener la violación). El segundo registro, triggerSync[1] de las capturas el estado metaestable y detiene la propagación por el resto de su lógica causando extraño problemas.

Su lógica en sí también parece raro. Yo sugeriría que la división en su detector de bordes de la lógica, y su contador:

reg triggerDly;
wire triggerEdge;
always @ (posedge clk) begin
    triggerDly <= triggerSync[1];
end
assign triggerEdge = (triggerDly != triggerSync[1]);

always @ (posedge clk) begin
    if (triggerEdge) begin
        trigger_count <= trigger_count + 1;
    end
end

La división de todo lo que hace el código más fácil de seguir y de depuración. También puede modificar fácilmente el detector de bordes de la lógica para ser flanco de subida, bajada, o ambos. Usted podría también hacer que el detector de bordes de un submódulo como un útil poco de código para su reutilización.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X