Salida en estado desconocido aunque se especifique en verilog

0

Estoy teniendo algunos problemas para crear un detector de bordes en verilog. Hasta ahora he encontrado esto:

module edge_detector (  
        input     ce,               // Clock enable.
        input     data,             // Data signal for edge detection.
        output reg detected,        // Output signal that goes high when edge is detected.
        input     reset,            // Active high reset.
        input     clk,              // Clock.
        input     [1:0] edge_sel,   // Edge selection. Look in description for details.
        output     sim_prev_data    // Simulation variable. Previous data state.
    );

    reg prev_data = 'bx;    // Previous data signal level state.

    always @(posedge clk) begin
        if (reset) begin
            detected <= 0;
            prev_data <= 'bx;
        end else if (ce) begin
            // Upon initialization or after reset prev_data state is unknown.
            // So after first clock tick prev_data is set, but detected output
            // should stay low.
            if (prev_data == 'bx) begin
                prev_data <= data;
                detected <= 0;
            end else begin
                case (edge_sel)
                    'b00: detected = (prev_data == 0 && data == 1);     // Rising edge.
                    'b01: detected = (prev_data == 1 && data == 0);     // Falling edge.                    
                    'b10: detected = ((prev_data == 0 && data == 1) ||  // Any edge.
                                      (prev_data == 1 && data == 0));       
                    'b11: detected = ((prev_data == 0 && data == 0) ||  // No edge change.
                                      (prev_data == 1 && data == 1));           
                endcase

                prev_data = data;
            end
        end
    end

    assign sim_prev_data = prev_data;
endmodule

La imagen representa la forma de onda de simulación generada por iverilog y gtkwave. Como se puede ver cuando reset=1 también detected=0 y prev_data=x . Cuando el restablecimiento se reduce y en el primer flanco ascendente de una marca de reloj, marcado por una línea roja, detected tiene un valor de x . Aunque he definido explícitamente detected<=0; en ...if (prev_data == 'bx) begin... ,

¿Por qué no detected tiene un valor de 0 después del restablecimiento?

    
pregunta Golaž

2 respuestas

1

Publiqué esto como un comentario, pero lo expandiré en una respuesta.

El operador de igualdad lógica es solo eso, lógico. Cualquier cosa que no sea un 1 o un 0 da como resultado una salida desconocida (x). El operador de igualdad de casos ( prev_data==='bx ) requerirá la coincidencia de x así como 0 y 1 . Sin embargo, el uso de x en la síntesis física no tiene sentido, un poco en el hardware será 1 o 0 .

Lo que su comentario describe Upon initialization or after reset prev_data state is unknown. no tiene sentido. Después de reiniciar, debes inicializar específicamente el valor a algo. En hardware físico, ¿cómo se puede distinguir x ? Un registro no puede ser x , solo 1 o 0 . Por lo tanto, debe asegurarse de que después de restablecerlo esté configurado en un valor conocido.

Si desea lograr lo que implica su comentario en el código, simplemente puede crear una señal de reinicio retrasado y usarla como una señal que se ha desactivado. Por ejemplo, lo siguiente lograría lo que usted describe:

reg prev_data = 'b0;    // Previous data signal level state.

reg exit_reset;
always @(posedge clk) begin
    if (reset || ce) begin
        exit_reset <= reset; // Exit reset is the reset signal delayed by one cycle, or until the clock is enabled.
    end
end

always @(posedge clk) begin
    if (reset) begin
        detected <= 0;
        prev_data <= 'b0; //Initialise to a known value
    end else if (ce) begin
        // Upon initialization or after reset prev_data state is incorrect.
        if (exit_reset) begin
            //If we just exited reset, then initialise prev_data but keep detected low.
            prev_data <= data;
            detected <= 0;
        end else begin
            ....
            prev_data = data;
        end
    end
end
    
respondido por el Tom Carpenter
1

detected es una función de la señal prev_data que no está definida en la instancia de reloj que indique.

Al reiniciar, debes establecer prev_data en algo. Para eso está el reinicio.

No creo que prev_data == 'bx tenga un significado práctico en absoluto ... 'bx no es un valor, por lo que no se puede comparar con un valor. Esto no se puede sintetizar. Si está tratando de hacer algo de comportamiento solamente, cambie el tipo de su variable y asigne algo diferente. Digamos que lo conviertes en un entero, luego usa -1 para "indefinido", 0 para 0 y 1 para 1.

    
respondido por el jpcgt

Lea otras preguntas en las etiquetas