1
\$\begingroup\$

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?

\$\endgroup\$
  • \$\begingroup\$ For question 2, what might be a value of x you are considering to be most problematic? \$\endgroup\$ – Andy aka Apr 7 '18 at 10:17
  • \$\begingroup\$ So you need a counter to holdoff and a counter to divide. This dual counter allows fractions rathern than integrers. Obviously decoded outputs with gates to enable counting. Or use a "fractional-N" PLL IC which also has counters in the output and return path so fo/fin=x1x2/y1y2 to dual counts in both directions ( forward and feedback). When fin is too high, sync. integer pre-scaler binary counters are used to get down to cheaper counters \$\endgroup\$ – Sunnyskyguy EE75 Apr 7 '18 at 14:43
1
\$\begingroup\$

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?
\$\endgroup\$
  • \$\begingroup\$ True, I want the counter to stay in each of its states for x clock cycles. Your implementation will work for integer number of cycles. But how would you handle fractional x? for example to make the counter increment after every 12.8 clocks on average? \$\endgroup\$ – frank_010 Apr 7 '18 at 16:32
  • \$\begingroup\$ Oh, is that what you meant by "fractional factor"? It really wasn't clear from your examples. In that case, DDS techniques can be applied, but you'll have to be a lot more specific about what kind of values x can take, and how you're representing x as a digital signal. \$\endgroup\$ – Dave Tweed Apr 7 '18 at 16:47
  • \$\begingroup\$ Yes, this will solve for both integer and fractional numbers. However, the current design is very much tied to max hold clocks being powers of 2. How would you handle the case where max hold clocks (x=1) is e.g 460 instead of 512? \$\endgroup\$ – frank_010 Apr 7 '18 at 18:22
  • \$\begingroup\$ Seriously? I've handed you these answers on a silver platter -- are you really incapable of generalizing from this? Yes, the shortcut of looking at temp[9] for overflow works only for powers of two, but it's easy to extend this to any number at all. I'm not going to do ALL of your homework for you! \$\endgroup\$ – Dave Tweed Apr 7 '18 at 19:02
  • \$\begingroup\$ @toolic: Thanks. I was just going by the fact that the SE syntax coloring seemed to be highlighting it as a keyword. \$\endgroup\$ – Dave Tweed Apr 9 '18 at 14:46
2
\$\begingroup\$

Maybe I would condition the main counter using a comparator which takes x and the output of the auxiliary 10 bits counter (clocked at clock frequency) as the inputs? I can't tell you more since some details about the functioning are missing in your description.

\$\endgroup\$
  • \$\begingroup\$ Let me know what additional info you require and I'll add that to the description \$\endgroup\$ – frank_010 Apr 7 '18 at 9:20
0
\$\begingroup\$

If we're talking fractional, then you need to define what resolution you need in frequency, which will determine the number of bits you need. More bits means more resource consumption, but you can specify a more precise fractional part. The way you implement this is as follows: build an N+1 bit accumulator, on every cycle add your N bit step to the accumulator. When the MSB toggles, increment your output counter.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.