Std_logic_arith vs. Numeric_std


Although it might appear that std_logic_arith is an IEEE supported package file, it is not. IEEE created the numeric_std package file and it is the official package file for performing mathematical operations in FPGAs. Std_logic_arith was created by Synopsis before IEEE created numeric_std. Since Synopsis had the first package file to do math, they gained a large user base. Unfortunately their package file is easy to use incorrectly, especially when doing unsigned and signed math. There are two main reasons for this:

  1. Synopsis' std_logic_arith file does not force you to be explicit in whether your signals are signed or unsigned.
  2. When doing both signed and unsigned math in one file, you will have conflicts with overloaded operators.

Let's look at the first issue. Std_logic_arith lets you do math operations on std_logic_vectors. So if I have an 8 bit std_logic_vector count and I want to add 1 to it I can do that. The problem is that the tools don't force you to be explicit. Is count unsigned or is it signed? This can create problems and you can design code that performs differently than you intended. When using numeric_std, you are not allowed to perform any mathematical operations on signals unless you have first declared them as either type signed or unsigned. Therefore in the example above, if count is always a positive number, you should declare it as unsigned.

Issue #2 can occur when you need to do math operations on both signed and unsigned types in the same file. Std_logic_arith uses overloaded functions to perform these tasks and they can conflict! This causes headaches, since now you might need to duplicate and separate code that belongs together.

For these reasons, always use numeric_std for mathematical operations. It might seem more tedious, but it prevents you from making mistakes and it forces you to be explicit with your intentions.