VHDL is a strong typed language. It is also a language which has quite a long history. These two facts together make handling of signed and unsigned numbers quite confusing. Even today I see lots of code examples with incorrect treatment of signed and unsigned arithmetic.
Part of the history of the VHDL language is the std_logic_arith library. This library is a non-standard library, or maybe I should say de-facto standard library, created by Sinopsis. I recommend not to use it, since there is an ieee library for arithmetic operations today, ieee.numeric
Adding to the confusion is the fact of how operations are made for binary coded numbers. Unsigned numbers represent natural number from zero to the maximum number that can be coded in the vector. If we use 8-bit vectors, we will be able to code values between 0-255. To represent signed numbers, one popular format is two’s complement. Using two’s-complement we can code numbers from -128 to 127 in an eight bit vector.
Unless told beforehand, VHDL has to know if a number is signed or unsigned. I will give you what I think are MUSTs and also some recommendations to work with number and avoid pitfalls.
- Use ieee.numeric_std. DO NOT use std_logic_arith.
- DO NOT use the signed or unsigned libraries. When you use these libraries, all the std_logic_vector arrays in the file are considered signed or unsigned by default. This can cause very difficult to track bugs.
- Always use std_logic_vector for your ports. Do not use signed or unsigned ports.
- Signals that should be treated as signed or unsigned are EXPLICITLY declared as such in your source file. If the signals are ports, they are converted back and forth to std_logic_vector inside each source file.
- integer fasten simulations. However, I must admit that I am not used to them. I use std_logic_vector, signed and unsigned as required. Of course, if a specific vector is used as an index to an array, it must be converted to integer first.
- Once you stick to numeric_std, the following figure explains all the transitions from each type to the other:
You may want to visit the code snippets page to see type conversion in action on several examples.