VHDL (VHSIC Hardware Description Language) is a hardware description language that was developed in the 1980s as part of the VHSIC (Very High-Speed Integrated Circuit) program initiated by the U.S. Department of Defense. The goal was to standardize the design process of digital systems and to provide a way to describe the structure and behavior of digital systems at a high level of abstraction.
VHDL was standardized by IEEE in 1987 (IEEE 1076-1987) and revised multiple times: VHDL-93, VHDL-2002, VHDL-2008, VHDL-2019.
Unlike standard software languages, VHDL describes concurrent operations mapping directly to hardware structures like logic gates, multiplexers, and flip-flops.
Who:
Developed under the U.S. Department of Defense, standardized by the IEEE.
Why:
VHDL was created to model digital systems and provide a standard for electronic design automation (EDA).
To verify the functionality of hardware designs before actual silicon implementation, saving millions in design cycles.
Strong Typing — Prevents design defects early with strict compile-time type validation (e.g. preventing adding boolean to std_logic_vector without conversion).
High Reusability — Easily parameterizes hardware bit-widths and architectures using Generics.
Vendor Independent — Standard hardware description runs across any target hardware (Xilinx/AMD, Intel/Altera, Microchip) and compilers.
Disadvantages
Verbosity — Requires extensive boilerplate statements for declarations (Entity, Component, Signal declaration, Port Maps), leading to very long source files.
Steep Learning Curve — Requires a paradigm shift: thinking in parallel hardware logic gates instead of sequential CPU cycles.
Strict Syntax Pitfalls — Type mismatching and signal assignment scheduling are often confusing for software programmers.
Remember Points
Concurrent vs. Sequential — Statements outside a process block execute concurrently. Statements inside a process block execute sequentially.
Signals vs. Variables — Signals update at the end of simulation cycles. Variables update immediately.
Basics
Library Declarations
-- Standard library package declarations (required for standard logic types)library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.NUMERIC_STD.ALL; -- Recommended for arithmetic operations
Design Units: Entity & Architecture
-- 1. Entity: Defines the external interface (I/O pins) of the componententity AND_Gate is port ( A : in std_logic; B : in std_logic; Y : out std_logic );end AND_Gate;-- 2. Architecture: Defines the internal implementation logic of the componentarchitecture Behavioral of AND_Gate isbegin Y <= A and B; -- Concurrent signal assignmentend Behavioral;
Comments
-- This is a single-line comment in VHDL.-- VHDL does not support native multi-line comment blocks.
Data Types
Standard Logic & Vector Types
-- std_logic: 9-value logic type defined in IEEE 1164:-- 'U' (Uninitialized), 'X' (Forced Unknown), '0' (Forced Low), '1' (Forced High)-- 'Z' (High Impedance), 'W' (Weak Unknown), 'L' (Weak Low), 'H' (Weak High), '-' (Don't care)signal clk : std_logic := '0'; -- single bitsignal bus_data : std_logic_vector(7 downto 0); -- 8-bit bus (MSB to LSB order)
Numeric Types
-- signed and unsigned types from numeric_std (support arithmetic)signal count_uns : unsigned(3 downto 0) := "0000";signal temp_sig : signed(7 downto 0);-- integer (holds standard 32-bit integer range)signal count_int : integer range 0 to 15 := 0;
Signals, Variables & Constants
Execution context
-- Signals: Hold values over time, updated after delta-delays (at process boundary/suspension)-- Variables: Used only inside PROCESS blocks, updated instantly (sequential context)architecture Dev of Test is signal sig_a : integer := 0; -- Signal declared in architecture bodybegin process(clk) variable var_b : integer := 0; -- Variable declared inside process begin if rising_edge(clk) then var_b := var_b + 1; -- Assignment := updates var_b immediately sig_a <= var_b; -- Assignment <= schedules sig_a to update at end of process end if; end process;end Dev;
Concurrent Statements
Conditional Assignments (when-else)
-- outside process: concurrent conditional signal assignmentY <= A when (sel = '1') else B;
Selected Assignments (with-select)
-- outside process: selected signal assignmentwith sel select Y <= A when "00", B when "01", C when others; -- default fallback (highly recommended to cover all 9 std_logic states)
Sequential Statements
Processes & Sensitivity Lists
-- Processes execute sequentially.-- The sensitivity list controls when the process triggers.process(A, B, sel) -- triggers if A, B, or sel changesbegin if sel = '1' then Y <= A; else Y <= B; end if;end process;
Case Statements
process(sel)begin case sel is when "00" => Y <= A; when "01" => Y <= B; when others => Y <= '0'; end case;end process;
Sequential Loops
-- For loops inside processes (unrolled by synthesis tools)process(bus_data) variable parity : std_logic := '0';begin parity := '0'; for i in 0 to 7 loop parity := parity xor bus_data(i); end loop; y_parity <= parity;end process;
Finite State Machines (FSM)
Two-Process FSM Implementation
architecture FSM_Arch of My_FSM is type state_type is (IDLE, READ_STATE, WRITE_STATE); signal current_state, next_state : state_type;begin -- 1. Sequential Process: State register updates on clock state_reg: process(clk, reset) begin if reset = '1' then current_state <= IDLE; elsif rising_edge(clk) then current_state <= next_state; end if; end process; -- 2. Combinational Process: Next state logic and outputs comb_logic: process(current_state, start_btn) begin case current_state is when IDLE => if start_btn = '1' then next_state <= READ_STATE; else next_state <= IDLE; end if; when READ_STATE => next_state <= WRITE_STATE; when WRITE_STATE => next_state <= IDLE; when others => next_state <= IDLE; end case; end process;end FSM_Arch;
Structural Modeling
Component Declaration & Instantiation
architecture Structural of TopLevel is -- Declare sub-component interface component AND_Gate is port ( A, B : in std_logic; Y : out std_logic ); end component; signal s1, s2 : std_logic;begin -- Instantiate sub-component (named port mapping) U1 : AND_Gate port map ( A => s1, B => s2, Y => out_pin );end Structural;
Generics
Parameterized Bit Widths
-- Generics parameterize design sizes (compiled before logic instantiation)entity N_Bit_Register is generic ( N : integer := 8 -- Default width is 8-bit ); port ( clk : in std_logic; d_in : in std_logic_vector(N-1 downto 0); q_out: out std_logic_vector(N-1 downto 0) );end N_Bit_Register;-- Instantiating parameterized components:-- U_Reg : N_Bit_Register generic map(N => 16) port map(clk, d, q);
Testbenches
Simulation Structure
-- Testbenches have no external ports (empty entity)entity tb_AND_Gate isend tb_AND_Gate;architecture Simulation of tb_AND_Gate is -- 1. Component declaration component AND_Gate is port (A, B : in std_logic; Y : out std_logic); end component; -- 2. Signal declarations signal tb_A, tb_B, tb_Y : std_logic := '0';begin -- 3. Unit Under Test (UUT) instantiation UUT: AND_Gate port map (A => tb_A, B => tb_B, Y => tb_Y); -- 4. Stimulus process stim_proc: process begin tb_A <= '0'; tb_B <= '0'; wait for 10 ns; assert tb_Y = '0' report "Error: 00 failed" severity error; tb_A <= '1'; tb_B <= '1'; wait for 10 ns; assert tb_Y = '1' report "Error: 11 failed" severity failure; wait; -- Suspends process indefinitely (stops simulation) end process;end Simulation;
Useful Packages & Functions
Type Conversions
-- Std_logic_vector to unsignedsignal u_val : unsigned(7 downto 0);u_val <= unsigned(bus_data);-- Unsigned to integersignal int_val : integer;int_val <= to_integer(u_val);-- Integer to unsigned/signed (requires output width size argument)u_val <= to_unsigned(15, 8); -- converts integer 15 to 8-bit unsigned vector