In the circuit below, I'm trying to count the number of clock pulses that happen while the decode
signal is high. In order to do this, I create a composite
wire that takes the AND of clk
and decode
, and increment a counter at the positive edges of this signal.
module countPulses(clk, decode);
input clk;
input decode;
wire composite = clk & decode;
reg [15:0] composite_counter = 16'h0000; // Increments too often
reg [15:0] delayed_counter = 16'h0000; // Lags 1 cycle behind desired
reg [15:0] desired = 16'h0001; // Intended counter behavior
always @(posedge composite)
begin
composite_counter <= composite_counter + 1;
desired <= desired + 1;
end
// Manually fix up the desired results on the falling edge of `decode`
always @(negedge decode)
desired <= desired - 1;
always @(posedge clk)
if (decode) delayed_counter <= delayed_counter + 1;
endmodule
Unfortunately, composite_counter
doesn't work as I expected. I'm looking for the values shown in desired
, but instead, composite_counter
increments again at the falling edge of the decode
signal. I don't understand why this happens, as you can see in the trace that when this occurs, composite
and decode
are both zero. There should be no overlap between the rising edge of clk
and the falling edge of decode
, but for some reason, it's being treated as a posedge
anyways. I'm new to Verilog and hardware design, so perhaps I'm misunderstanding how @ posedge
works.
I also tried incrementing a counter (delayed_counter
) at posedge clk
instead of posedge composite
and checking if decode
is high. This doesn't exhibit the double-counting behavior that composite_counter
does, but the values are delayed one cycle from those in desired
. I understand why this is happening, but wanted to point it out as a potential solution that won't work.
With that, my two questions are:
- Why does
always @(posedge composite)
fire whencomposite
is (and remains) zero? - How can I achieve the behavior shown by
desired
without resorting to such haphazard techniques as decrementing the counter on the falling edge of thedecode
signal?
Best Answer
You have a race condition between the falling edge of
decode
and the rising edge ofclock
.Zoom in your wave viewer and you’ll probably see
composite
going high very briefly at that edge.To fix it, make sure that
decode
goes low some nonzero time beforeclock
goes high. Or, even better, instead of using a gated clock (google this term if you don’t know it), usedecode
as an enable signal, andclock
as a clock.