Skip to content

VHDL · Chapter 10.5 · Packages and Reuse

The Standard IEEE Packages

You have used standard packages since lesson one, and now you see the landscape whole. The std library is implicit and gives you the built-in types such as boolean, integer, time, and character. The ieee library holds the packages you import. One provides the standard logic type system with resolution, the rising-edge function, and basic conversions. Another adds the unsigned and signed numeric types with arithmetic, comparison, and conversions. A third handles file and console input and output for testbenches. Knowing what lives where, and which packages are obsolete, such as the old non-standard arithmetic family, is what keeps your library and use clauses correct and your code portable across tools and vendors. This lesson maps the standard packages and how to reach each one.

Foundation13 min readVHDLIEEEstd_logic_1164numeric_stdStandard PackagesReuse

1. Engineering intuition — the libraries you stand on

Almost no VHDL is written from bare language primitives; it stands on a small set of standard packages that the whole industry shares. The language itself (the std library) gives you boolean, integer, time, and character for free. The ieee library adds the hardware-modelling layer: the nine-valued std_logic system, the unsigned/signed numeric types, and I/O for testbenches. Because these are standard, code that uses them is portable across tools and vendors — and code that uses the old, non-standard arithmetic packages is not. Knowing the map tells you exactly which library/use clauses any module needs.

2. Formal explanation — the standard package map

standard_packages.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- STD library (IMPLICIT — no library/use needed): boolean, integer, natural, positive,
--   character, string, time, severity_level, ... (the built-in types, lessons 2.x).
 
library ieee;
use ieee.std_logic_1164.all;   -- std_logic, std_ulogic, std_logic_vector; resolution;
                               -- rising_edge/falling_edge; to_bit/to_stdlogic conversions
use ieee.numeric_std.all;      -- unsigned, signed; +,-,*, comparisons; to_unsigned/to_signed,
                               -- to_integer, resize, shift_left/right (the arithmetic layer)
 
-- TESTBENCH I/O (simulation):
use std.textio.all;            -- line, file I/O (read/write/readline/writeline)
use ieee.std_logic_textio.all; -- read/write of std_logic types (older flows; some in 1164 in 2008)
-- ieee.math_real : real-valued math for testbenches/models (NOT synthesizable)

The std library is implicit (its standard package is always visible). The ieee library is explicit (library ieee; use ieee....): std_logic_1164 provides the logic-value type system and edge functions; numeric_std provides the numeric types and arithmetic; textio and math_real support testbenches. Reach each with the right use clause.

3. Production usage — the canonical preamble

canonical_preamble.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
library ieee;
use ieee.std_logic_1164.all;   -- logic values + edges  (synthesizable RTL)
use ieee.numeric_std.all;      -- numbers + arithmetic   (synthesizable RTL)
-- (testbenches add: use std.textio.all; and possibly ieee.std_logic_textio.all / ieee.math_real.all)
 
entity counter is
  port ( clk, rst_n : in std_logic; q : out std_logic_vector(7 downto 0) );
end entity;
architecture rtl of counter is
  signal cnt : unsigned(7 downto 0);            -- numeric_std type
begin
  process (clk) begin
    if rising_edge(clk) then                    -- std_logic_1164 function
      if rst_n = '0' then cnt <= (others => '0');
      else                cnt <= cnt + 1;       -- numeric_std arithmetic
      end if;
    end if;
  end process;
  q <= std_logic_vector(cnt);                   -- numeric_std conversion
end architecture;

What hardware does this become? A counter — but the point is the preamble: std_logic_1164 supplies std_logic, std_logic_vector, and rising_edge; numeric_std supplies unsigned, +, and the std_logic_vector(...) conversion. This two-line use pair is the standard, portable foundation for essentially all synthesizable RTL.

4. Structural interpretation — the standard-package landscape

standard package map: std built-ins, ieee std_logic_1164 and numeric_std, testbench packages, and obsolete onesRTL layerRTL layertestbenchstd (implicit)boolean, integer, time,characterieee.std_logic_1164std_logic(_vector),rising_edge, resolutionieee.numeric_stdunsigned/signed,arithmetic, conversionstextio / math_realtestbench I/O + real math(sim only)std_logic_arith /_unsignedOBSOLETE — avoid12
The standard package landscape. The implicit std library provides the language's built-in types (boolean, integer, time, character). The ieee library provides the modelling layer: std_logic_1164 (the nine-valued logic type system, resolution, rising_edge/falling_edge, basic conversions) and numeric_std (unsigned/signed with arithmetic, comparison, and conversions) — the two you import for almost all RTL — plus textio and math_real for testbenches. The std_logic_arith / std_logic_unsigned / std_logic_signed family is OBSOLETE (Synopsys legacy, not IEEE) and must be avoided in favour of numeric_std. This is a source/library structure, captured by a map rather than a waveform.

5. Why this is structural, not timing

These packages define what types and operations exist, a source/library structure, so the right picture is the map above, not a waveform — their run-time effect is just the behaviour of the types and functions you call (an adder from numeric_std, an edge test from std_logic_1164), which you have already seen in earlier lessons. The practical knowledge here is where each thing lives so your library/use clauses are correct and portable: std_logic_1164 + numeric_std for synthesizable RTL, textio/math_real for testbenches only.

6. Debugging example — the obsolete package (and the missing use)

Expected: portable, correct arithmetic. Observed: non-portable behaviour or ambiguous-overload errors across tools, or an unknown-identifier error for unsigned/rising_edge. Root cause: the code imported the obsolete std_logic_arith/std_logic_unsigned (Synopsys legacy, not IEEE) which overloads arithmetic onto std_logic_vector non-portably, or it simply omitted the use ieee.numeric_std.all; / use ieee.std_logic_1164.all; clause so the standard names were not visible. Fix: use numeric_std on unsigned/signed (never std_logic_unsigned), and include both standard use clauses. Engineering takeaway: for portable RTL, the arithmetic package is numeric_std; the std_logic_arith family is obsolete, and every module needs std_logic_1164 + numeric_std imported.

standard_not_obsolete.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- BUG: obsolete, non-standard arithmetic on std_logic_vector.
-- use ieee.std_logic_unsigned.all;  signal s : std_logic_vector(7 downto 0); s <= a + b;
-- FIX: numeric_std on unsigned/signed.
use ieee.numeric_std.all;  signal s : unsigned(7 downto 0);  s <= a + b;

7. Common mistakes & what to watch for

  • Using std_logic_arith/std_logic_unsigned/std_logic_signed. Obsolete and non-portable; use numeric_std.
  • Omitting a use clause. unsigned/rising_edge/etc. are unknown without numeric_std/std_logic_1164.
  • Forgetting library ieee; before use ieee..... Name the library first (std and work are implicit).
  • Using math_real/textio in synthesizable RTL. They are simulation/testbench only; keep them out of synthesizable code.
  • Mixing numeric packages. Stick to numeric_std; mixing it with the legacy arithmetic packages causes ambiguous overloads.

8. Engineering insight & continuity

The standard packages are the shared foundation everyone builds on: std for the language's built-in types, and the ieee library's std_logic_1164 and numeric_std for the logic-value and numeric layers that essentially all RTL imports — with textio/math_real reserved for testbenches and the std_logic_arith family avoided as obsolete. Knowing the map keeps your library/use clauses correct and your code portable. With sharing (constants, types), build order, and the standard packages covered, the module closes by stepping back to methodology: the next lesson, Designing for Reuse, brings packages, generics, and entities together into a strategy for organising a project's shared code so it scales.