Electronic – CPLD is (sometimes) not incrementing counter

counterfpgaprogrammable-logicverilog

I have this simple program running on the Altera EPM240 that’s sometimes not doing the counter increment.

reg trigger_state;
reg [7:0] trigger_count;

always @ (posedge clk)
begin
    if (trigger != trigger_state) begin
      trigger_state <= !trigger_state;
      trigger_count <= trigger_count + 1;
    end
end

clk is running at 50 MHz, and the trigger signal in the picture at 1-2 kHz.

Enter image description here

In the picture (trigger=6, trigger_state=4, trigger_count[1]=1, trigger_count[0]=2)

As you can see, trigger_state always follows the input signal (trigger), but the counter (2) is sometimes not incremented.

What could explain such a behavior?

Best Answer

Fist of all:
Your trigger is coming in a-synchronous to the clock. You must first synchronize it before you can safely use it. The code for that is:

reg sync_trigger,safe_trigger;
always @(posedge clk)
begin
    sync_trigger <= trigger;
    safe_trigger <= sync_trigger;
end

The behavior your are seeing is because the hardware will more look like this:

if (trigger != trigger_state) 
  trigger_state <= !trigger_state;

if (trigger != trigger_state) 
  trigger_count <= trigger_count + 1;

As the trigger is a-synchronous you can have that one if is true and the other is false. Thus one is acted up and the other not. In fact it is implemented for every BIT of your counter so some bits may increment and others not.

Post thought:
Your trigger must be slower then your clock otherwise you will miss triggers!