Electronic – Design of a counter that stays in each state for x clocks

counterdigital-logicfpgaverilog

Suppose we have an 8-bit counter out[7:0]

It needs to stay in each count for specified number of clocks x, where x can be any integer or fractional factor of 512.

My Approach:

Use 10 bit counter temp[9:0] that increments on every posedge clock

For x=512, increment temp in steps of 1, and increment out when temp[9]==1

For x=256, increment temp in steps of 2, and increment out when temp[9]==1
….and so on.

My Question

  1. Does anyone have a better idea than this, more resource efficient?

  2. How to handle the case when x can take arbitrary values not necessarily related by factors of a particular number? We only know the max that x can be.


To clarify: x is just a normal 9 bit register. The value in x and number of hold clocks are related by 512/x = HoldClocks.

  • 512/1 = 512
  • 512/2 = 256
  • 512/3 = 170.667
  • 512/4 = 128
  • ……..
  • 512/512 = 1.

How about the general case? What if max hold clocks isn't a power of 2? How would you handle the case where max hold clocks (x=1) is e.g 460 instead of 512?

Best Answer

Your question says "a particular state", but it sounds like you want out[7:0] to stay in each of its states for x clock cycles. If so, then you want to use temp[9:0] as a "prescaler" — for every x clocks, you want to send one pulse to the out counter. This works for any value of x.

For every clock cycle, check to see whether temp equals x-1. If so, set temp to zero and increment out; otherwise, just increment temp.

In Verilog:

always @(posedge clock) begin
  if (temp >= (x-1)) begin
    temp <= O;
    count <= count + 1;
  end else begin
    temp <= temp + 1;
  end
end

OK, now that the you have clarified the meaning of x, the following DDS code will implement what you want directly.

always @(posedge clock) begin
  temp <= (temp & 10'h1FF) + x;
  if (temp[9]) count <= count + 1;
end

If x=1, count will only increment once every 512 clocks. If x=512, count will increment on every clock. If x=40, count will increment every 12.8 clocks on average.


In the general case of having two numbers, where the counting rate is x/y (x must be no greater than y), think about what the code above is actually doing with respect to the value y=512:

  • What does the expression temp & 10'h1FF actually accomplish numerically?
  • Similarly, what does looking at bit 9 being set mean numerically?