No hay suficiente información en su pregunta sobre la mejor manera de abordar esto. Sin embargo haré dos suposiciones:
- Las señales están condicionadas (es decir, sin pulsos espurios o bordes ruidosos)
- 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.