The problem is most likely meta-stability caused by using an asynchronous signal (your input trigger
) to control your counter.
When bringing any signal in, you need to make sure it is synchronised to the clock signal using a multi-register synchroniser chain. Something like:
reg [1:0] triggerSync;
always @ (posedge clk) begin
triggerSync <= {triggerSync[0],trigger}
end
Then use triggerSync[1]
in your code. The first register triggerSync[0]
will synchronise the signal but may go metastable if the input changes as the clock is changing (setup/hold violation). The second register triggerSync[1]
catches the metastable state and stops it propagating through the rest of your logic causing weird glitches.
Your logic itself also seems weird. I would suggest splitting it up into your edge detector logic, and your counter:
reg triggerDly;
wire triggerEdge;
always @ (posedge clk) begin
triggerDly <= triggerSync[1];
end
assign triggerEdge = (triggerDly != triggerSync[1]);
always @ (posedge clk) begin
if (triggerEdge) begin
trigger_count <= trigger_count + 1;
end
end
Splitting everything up makes the code easier to follow and debug. You can also easily modify the edge detector logic to be rising edge, falling edge, or both. You might as well also make the edge detector a submodule as its a useful bit of code to reuse.