VHDL: integers for synthesis?

Integers are fine in synthesis, I use them all the time.

I use std_logic at top level ports, but internally I was using ranged integers all over the place

That's fine!

Be aware:

  • You are simulating first aren't you :) - Integer types don't automatically "roll-over" in simulation - it's an error to go out of the range you've specified for them. If you want roll-over behaviour, you have to code it explicitly.
  • They are only specced to go from \$-(2^{31}-1)\$ to \$+2^{31}-1\$ (i.e. not quite the full range of a 32-bit integer, you can't use \$-2^{31}\$ and remain portable), which is a bit of a pain at times. If you need to use "big" numbers, you'll have to use unsigned and signed.
  • If you don't constrain them, you can sometimes end up with 32-bit counters where less would do (if the synth and subsequent tools can't "see" that they could optimise bits away).

On the upside:

  • They are much faster to simulate than unsigned/signed vectors
  • They don't automatically roll-over in simulation (yes, it's in both lists :). This is handy - for example you get early warning that your counter is too small.

When you do use vector types, you are using ieee.numeric_std, not ieee.std_logic_arith aren't you?

I use integers where I can, but if I explicitly want "roll-over n-bit counters", I tend to use unsigned.


Jan Decaluwe wrote an entire white paper on the problems of integers versus bit vectors. I expect his answers would be to use integers whenever possible. http://www.jandecaluwe.com/hdldesign/counting.html


There's nothing wrong about using integers for RTL per se, but there are reasons that some avoid it. This really is a question about subjective "best practice" and you'll eventually have to find out yourself what you prefer. As a help to that, I'll share my experience and thoughts on this.

Principally , I'm in favour of using (constrained) integers, also when writing for synthesis. I sometimes do it, but in practice, usually I stick to signed and unsigned. I'll elaborate on why.

You will be forced to use a vectorized datatypes in part of your design anyway:

  • Hardly any vendor-IP or 3rd party-IP will use integer type for ports

  • E.g. when sending data through BlockRam, even if you infer it and therefore never need to interface to any IP/macro/primitive, you'll most likely need to convert to vectorized type anyway

  • Even if neither of the above apply, you will mostly need to interface to something else at some point (a top-level port, if nothing else)

Since you can't use integer for the full design, you might want to skip it all together, because:

  • At some points, you'll need to do the conversions anyway, and this takes away part of the point of using integer in the first place

  • Also, for simulation, these conversions will typically be called with vectors of 'U' or 'X', either before reset, or at other times, and every single such function call will generate a warning messages from the package function, cluttering your simulation warnings/prompt

Drawbacks of using integer:

  • Contrary to the vectorized types, integers don't have 'U' and 'X'; I find those very helpful in simulations. You see how uninitialized signals propagate through the design, and you will probably react if you see a lot of uninitialized signals after the reset. This won't be the case if using integers.

  • With integers, there's a greater risk of simulation/synthesis mis-match when adding or subtracting resulting in under-/overflow. (As already pointed out by someone else.)

Typical cases where I find integer to really be a good option:

  • For debug signals/counters that you monitor through chipScope/signalTap etc.

  • Totally internal representation of counters, that never go into or out of your own code. Yes, there are such cases, e.g. if you're writing a FIFO and you are dead-reckoning writes/reads to form the signals full, empty, almostFull etc. (however arithmetics on the pointers is a better way than dead-reckoning in this case...)

My own conclusions: I do use integers sometimes, but sparingly, and mostly in the cases described above. I don't see much overhead in using unsignedand signed instead of integer, and therefore, usually stick to them.

Tags:

Vhdl

Synthesis