0
0
VhdlComparisonBeginner · 4 min read

std_logic_arith vs numeric_std in VHDL: Key Differences and Usage

In VHDL, std_logic_arith is a non-standard, vendor-specific library providing arithmetic operations on std_logic_vector, while numeric_std is the IEEE standard library offering well-defined numeric types like unsigned and signed. numeric_std is preferred for portability and clarity, whereas std_logic_arith is often legacy or vendor-dependent.
⚖️

Quick Comparison

Here is a quick side-by-side comparison of std_logic_arith and numeric_std libraries in VHDL.

Featurestd_logic_arithnumeric_std
StandardizationNon-standard, vendor-specificIEEE standard
Numeric TypesUses std_logic_vector with overloaded operatorsDefines unsigned and signed types explicitly
PortabilityLess portable, may vary by vendorHighly portable across tools
Type SafetyLower, uses std_logic_vector for numbersHigher, distinct numeric types
Operator OverloadingYes, but inconsistentConsistent and well-defined
Recommended UseLegacy or vendor-specific codeModern, portable VHDL designs
⚖️

Key Differences

std_logic_arith is a library originally created by some FPGA vendors like Synopsys and Altera. It provides arithmetic operations on std_logic_vector types by overloading operators, but it is not part of the official IEEE VHDL standard. This can cause portability issues when moving code between different tools or vendors.

On the other hand, numeric_std is an IEEE standard library that defines explicit numeric types: unsigned and signed. These types clearly represent numbers, improving code readability and type safety. Arithmetic operations are well-defined and consistent.

Using numeric_std helps avoid confusion because it separates numeric data from raw bit vectors. It also reduces errors by enforcing type correctness. In contrast, std_logic_arith treats numbers as bit vectors, which can lead to subtle bugs if not handled carefully.

⚖️

Code Comparison

Here is an example of adding two 4-bit numbers using std_logic_arith:

vhdl
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity add_std_logic_arith is
    port(
        a, b : in std_logic_vector(3 downto 0);
        sum  : out std_logic_vector(4 downto 0)
    );
end add_std_logic_arith;

architecture rtl of add_std_logic_arith is
begin
    sum <= ('0' & a) + ('0' & b);
end rtl;
↔️

numeric_std Equivalent

The same addition using numeric_std looks like this:

vhdl
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity add_numeric_std is
    port(
        a, b : in unsigned(3 downto 0);
        sum  : out unsigned(4 downto 0)
    );
end add_numeric_std;

architecture rtl of add_numeric_std is
begin
    sum <= ('0' & a) + ('0' & b);
end rtl;
🎯

When to Use Which

Choose numeric_std for all new VHDL designs because it is the IEEE standard, offers better type safety, and improves code clarity and portability. It clearly distinguishes numeric data from raw bit vectors, reducing bugs.

Use std_logic_arith only if you are maintaining legacy code or working with vendor-specific tools that require it. Avoid it for new projects to ensure your code works across different VHDL tools and environments.

Key Takeaways

numeric_std is the IEEE standard and preferred for modern VHDL coding.
std_logic_arith is non-standard and less portable, mainly for legacy or vendor-specific use.
numeric_std provides explicit numeric types improving readability and safety.
Avoid mixing std_logic_vector with arithmetic; use unsigned or signed from numeric_std instead.
Choose numeric_std to write portable, clear, and maintainable VHDL code.