I use VHDL-200X in ISE.I always use data type like std_logic_vector
,std_logic
,integer
,boolean
and real
.Alway
Never use std_logic_arith
or std_logic_**signed
. Always use numeric_std
when signed or unsigned values are needed. The former packages claim to be IEEE, but they aren't. They are vendor specific extensions from Synopsys or Mentor Graphics.
Both defined arithmetic operations on std_logic_vector
based on the imported packages. This e.g. means you can't used signed and unsigned values in the same architecture.
Doing all math in integer
s has some drawbacks:
My purist side agrees with @Pabbles. OTOH, my pragmatic side dissents. My pragmatic side wins, and hence, I recommend the following (until numeric_std_unsigned is supported):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
For RTL design, I recommend that you use types signed and unsigned for all operations you consider to be math. This is my purist side.
In RTL, I never recommend doing math in std_logic_vector, instead, std_logic_unsigned is just there for a safety net. Consider that all relational operators are implicitly defined (=, /=, <, <=, >, >-). In a design, we do a lot of comparisons to values:
if A = "00001" then
. . .
if B = X"1A" then
What happens if A is not 5 bits? What happens if B is not 8 bits? If you use the implicitly defined comparison, it is FALSE. If you use the comparison from std_logic_unsigned, it is ok if the sizes are different. If you are not using std_logic_unsigned, your testbench should find this issue.
Since "=" is ok to use with RTL, what if someone is doing an address decoder and writes:
Sel <= '1' when Addr > X"3FFF" else '0' ;
If A is 16 bits, then it should work out ok. What if A is not 16 bits? Then it does a lexicographic (dictionary ordered) comparison. IE: "100" > "01111" is TRUE.
With std_logic_unsigned, these will be handled by unsigned math rules. Which for most cases is correct. Without std_logic_unsigned, these will result in FALSE. If you are not using std_logic_unsigned and you are careful with your testbenches, you should find this.
My concern is that if you don't use std_logic_unsigned then you have a potential that the circuit that you simulate will be different than the circuit that you synthesize (as the synthesis tools tend to create an implementation that is consistent with std_logic_unsigned). If you miss catching this in simulation, it will be real difficult to find in a review. Hence, I recommend std_logic_unsigned as a safety net when using ordinary relational operators.
Note that VHDL-2008 introduces the package numeric_std_unsigned and I plan on switching to that when it works across all synthesis tools.
My really strict side says that we should address the issues with the ordering operations (<, <=, >, >=) by creating additional packages that also overload them for std_logic_vector, and hence, use of them results in an error due to ambiguity. Note we cannot protect "=" this same way.
VHDL-2008 adds matching relational operations "?=", "?/=", "?>", ... when these are available in your synthesis tools, I recommend switching to these. The matching equality operations (?=, ?/=) require operands to be the same length - meaning compile error if they are not equal length. The matching ordering operations (?>, ?>=, ?<, ?<=) are only defined in a math package such as numeric_std or numeric_std_unsigned - hence, you cannot use them unless you are using an appropriate math package.