11
\$\begingroup\$

I am learning to use an FPGA (Papilio development board,which has a xilinx spartan3e, using vhdl).

I need to divide an incoming pulse by a (hard coded) number.

I can see 3 options - roughly, as pseudocode (using 10 counts as an example):

  1. Initialize to 0, on input rising edge increase by 1, compare to 10; if they are equal, reset to 0 and trigger output pulse
  2. Initialize to 10, on input rising edge decrease by 1, compare to 0; if they are equal, reset to 10 and trigger output pulse
  3. Initialize to 9, but make sure there is at least 1 leading "0" bit, which is my output bit. On input rising edge decrease by 1. On rising edge of the output bit, reset.

The duty cycle is unimportant.

Is one of these better than the others? Is there an even better method that I haven't thought of?

Is there a "standard" way that will give the compiler the best chance of optimizing?

\$\endgroup\$
3
  • 3
    \$\begingroup\$ That's only three options :-) ... But seriously, it really doesn't matter all that much in an FPGA. The individual logic elements are general enough that it takes about the same number of resources and gives you the same performance whichever way you do it. The decision comes down to whether it is useful elsewhere in the design to have the numbers counting up or down or some other pattern. \$\endgroup\$
    – Dave Tweed
    Commented Dec 28, 2017 at 14:35
  • 2
    \$\begingroup\$ 4th option: 10-bit circular shift register loaded with "1000000000" and shifted on a rising edge. Use one bit of the shift register as the enable for what you are doing. \$\endgroup\$
    – Lincoln
    Commented Dec 28, 2017 at 14:50
  • 1
    \$\begingroup\$ As a side note - your compiler/fitter GUI tool, after finishing the job, should have an option showing you actual circuit it created at various abstraction levels, down to gates, so you should be able to see how the tool fitted your circuit and then you can make appropriate changes to the source. \$\endgroup\$
    – Anonymous
    Commented Dec 28, 2017 at 16:36

4 Answers 4

12
\$\begingroup\$

Optimizing to this level will break your heart. The result could change because of the technology of the FPGA you're using, other factors in the FPGA, but also because of factors outside of your control, including the fitter's random number seed.

Having said that, I believe that option 3 will be the best. Options 1 and 2 have a comparator/OR gate going between the counters so that it can signal that the target number has been reached. Option 2 may be slightly faster than 1, since it all can be straight OR'd together without any inverters, but again you run into small technology differences where it may be faster to AND or XOR.

Option 3 skips the comparison for the low cost of one extra bit in the counter. This should be worth it, unless you are severely restricted in flip-flops.

One fun fact about counters is that they tend to be grouped into a device specific size within a logic block, and you will see the timing change more than expected if this extra bit pushes you out of that group.

\$\endgroup\$
1
  • \$\begingroup\$ +1, barring clock speeds that push the limitations of the technology one should let the timing report guide their timing optimizations. Chasing hundreds of picoseconds on a Spartan 3e, or any FPGA for that matter, without cause is generally waste of time. \$\endgroup\$
    – jalalipop
    Commented Jan 2, 2018 at 13:12
4
\$\begingroup\$

One other option would be to initialize the counter to 6 (=24 - 10), count up, and then reset when the carry output activates (i.e., the FFs are all ones).

The advantage of this is that it doesn't require an extra FF, and many FGPAs have dedicated auxiliary logic to speed up this kind of carry operation in a counter or adder circuit.

\$\endgroup\$
3
\$\begingroup\$

Depends. For example: flip-flop propagation delay for 0→1 and 1→0 can be different, and hence a counter's transition delays for 000→001 and 001→000 can be slightly different. It may be higher or lower, depending on the cmos technology used in FPGA. So you have to synthesize and find out which one has better timing performance.

\$\endgroup\$
3
\$\begingroup\$

From a compiler writer's perspective: if you use integer, the internal representation is undefined, and the compiler is free to choose the most efficient implementation.

If you force a particular internal representation, the optimizer will still attempt to improve it, but it will start from a slightly worse vantage point.

Some FPGAs have "preload" capabilities, where registers can be initialized to arbitrary values, in which case initializing to \$N-1\$, counting down and using the topmost carry bit as output and reset (in the next cycle) is more efficient than implementing both an adder and a comparator. Without preload, an adder might be better.

Unless you know the internal structure, the resources allocated to other logic (many FPGAs have dedicated floating point multiply-add logic that you can also use to implement a counter if you have leftover units) and are entirely sure that you won't be switching to a different model, the answer is "don't think about it".

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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