I am having some troubles with creating an edge detector in verilog. So far I've come up with this:
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
Picture represents simulation waveform generated by iverilog and gtkwave. As can be seen when reset=1
also detected=0
and prev_data=x
. When reset goes low and on first rising edge of a clock tick, marked by red line, detected
has a value of x
. Even though I have explicitly defined detected<=0;
under ...if (prev_data == 'bx) begin...
,
Why doesnt detected
have a value of 0 after reset?