comparar borde ascendente ocurrió antes o después de otro borde con verilog

0

Me gustaría escribir un código verilog para generar el nivel RTL para señal B como se muestra en la figura. Ha pasado mucho tiempo desde que escribí verilog en la escuela, así que estoy bastante oxidado por esto. Digamos que tengo dos señales A, B como en la imagen y necesito generar la señal C con la descripción a continuación.

El flanco ascendente de la señal C se determina de la siguiente manera:

  1. En el flanco descendente de la señal A, si se produce el flanco ascendente de la señal B, antes del flanco descendente de la señal A.
  2. En el flanco ascendente de la señal B, si se produce el flanco ascendente de la señal B después del flanco descendente de la señal A.
    (es posible que desee ver la imagen para comprender mejor la regla)

El ciclo de trabajo de la señal C es igual al ciclo de trabajo de la señal A.

Estoy atascado en la parte para comparar si el flanco ascendente de la señal B se produjo ANTES o DESPUÉS del flanco descendente de la señal A. Espero que alguien pueda ayudarme en esto.

    
pregunta anhnha

1 respuesta

1

No hay suficiente información en su pregunta sobre la mejor manera de abordar esto. Sin embargo haré dos suposiciones:

  1. Las señales están condicionadas (es decir, sin pulsos espurios o bordes ruidosos)
  2. Puedes muestrear las señales con un reloj rápido para hacerlas sincrónicas. Esto significa que simplemente puede verificar las señales en puntos de tiempo discretos en lugar de asincrónicamente.

Dados estos supuestos, el enfoque que utilizaría es detectar los bordes de las señales utilizando un simple detector de borde síncrono. Luego puede usar una máquina de estado para determinar el orden de los eventos.

//First we sample the signals with fast clock and perform edge detection.
//This gives us a series of discrete time points to work with
reg aDly, bDly;
reg aFall, bRise;
always @ (posedge fastClock) begin
    aDly <= a;
    bDly <= b;
    aFall <=  aDly && !a; //Falling edge of a when aDly high and a low.
    bRise <= !bDly &&  b; //Rising edge of b when bDly low and b high.
end

reg someEvent; //Set this high when c needs to fall.

//Now we do the logic for C with a state machine.
localparam IDLE_STATE   = 2'b00;
localparam AFIRST_STATE = 2'b01;
localparam BFIRST_STATE = 2'b10;

reg [1:0] stateMachine;
reg       c;

always @ (posedge fastClock or posedge reset) begin
    if (reset) begin
        stateMachine <= IDLE_STATE;
        c            <= 1'b0;
    end else begin
        case (stateMachine) begin
            IDLE_STATE: begin //Wait for the start of an event sequence.
                //If the start of a sequnece
                if (bRise && aFall) begin
                    //If both happen at the same time
                    c               <= 1'b1;            //C goes high immediately.
                end else if (aFall) begin
                    //If falling edge of a comes first
                    c               <= 1'b0;            //C stays low.
                    stateMachine    <= AFIRST_STATE;    //And go on to wait for b rising.
                end else if (bRise) begin
                    //If rising edge of b comes first
                    c               <= 1'b0;            //C stays low.
                    stateMachine    <= BFIRST_STATE;    //And go on to wait for a falling.
                end else if (someEvent) begin
                    //Work out when C should go low - I can't tell this from your description
                    c               <= 1'b0;            //C goes low.
                end
            end
            AFIRST_STATE: begin //Wait for rising edge of b
                if (bRise) begin
                    //Once rising edge of b occurs,
                    c               <= 1'b1;            //C goes high.
                    stateMachine    <= IDLE_STATE ;     //Return to idle.
                end
            end
            BFIRST_STATE: begin //Wait for falling edge of a
                if (aFall) begin
                    //Once rising edge of b occurs,
                    c               <= 1'b1;            //C goes high.
                    stateMachine    <= IDLE_STATE ;     //Return to idle.
                end
            end
        endcase
    end
end

Necesitará determinar qué lógica usar para determinar cuándo C debe bajar. No puedo decir esto de tu pregunta.

Si desea un ancho fijo, puede usar un contador que se activa cuando C sube el nivel.

    
respondido por el Tom Carpenter

Lea otras preguntas en las etiquetas