Electronic – CPLD best practice for resetting a counter

best practicecounterprogrammable-logic

My application has a bog-standard count-until-a-certain-number-then-reset-the-counter section. My experienced friend tells me that when using actual chips, it's common to increment the counter on the rising edge of the clock and reset the counter on the falling edge. That way the designer has a lot of time to do what needs to be done before the next clock arrives.

But he's never used a CPLD and I wonder if this changes the rules. Or if his information is technically sensible but not practically needed.

My design has something like

always @(posedge clock) begin (increment the clock) end
always @(negedge clock) begin (reset the counter conditionally) end

I'm not trained at all in electrical engineering, I just read and dabble. But I can't let it rest when I don't feel I have a certain (n00b-level) understanding of what's going on.

I just read an example from a university course where the instructor didn't care about when the counter was reset. His design was something like:

always @(posedge clock) begin
    counter = counter + 1;
    if (counter == some_number) counter = 0;
    end

This leads me to believe I'm over-engineering, the instructor is instructing not building an industrial app, or the synthesis process handles such things.

Of course I could try it in the simulator or actually plop it into the CPLD. Eventually this is going to be driving a powerful machine and it's got to work every time. I can't have an edge case where the machine misbehaves.

EDIT – more context. While it may not matter with respect to the answer, I am counting pulses generated by an encoder attached to a rotating spindle. I have to count every one of them, and I can't lose any.

EDIT 2 – example of a loop that increments a counter, then on some condition, changes it.

module slow_count(
    input clk,
    output reg [3:0] count
    );

    reg[19:0] snooze = 0;
    always @(posedge clk) begin
        snooze = snooze + 1;            // Set the counter
        if (snooze == 1000000) begin
            snooze = 0;             // And change it here
            count = count + 1;
            if (count == 10) count = 0;
            end
        end

endmodule

Best Answer

It sounds like you don't have an external reset signal to respond to, you just want to count to some number then go to zero as the next step. You could consider this a mod n counter, where n is one more than the maximum count in your counter.

So I'm not sure what you mean about "losing a signal" while doing the reset. If you had a 3-digit decimal counter and it rolled over from 999 to 000, you wouldn't consider it as "losing a signal", it would just be counting to the next value in mod-1000 arithmetic.

So if you do

always @(posedge clock) begin
    if (counter == some_number) begin
         counter <= 0;
    end
    else begin
        counter <= counter + 1;
    end
end

You'll have a counter that counts continuously in mod-some_number+1 arithmetic. Alternately you could say it counts to some_number, then resets to zero without ever "losing" a clock pulse.

If some_number+1 happens to be a power of 2, you don't even need the reset condition in your code. For example, for a mod-16 counter, you can just use a 4-bit counter, and the synthesized logic will count continuously and repeatedly from 0 to 15.