Comprehensive VHDL Code Examples for Digital Design

Digital Flip-Flops and Registers

1. D Flip-Flops Without Asynchronous Reset

  • D flip-flop without asynchronous reset
  • D flip-flop with asynchronous reset
  • D flip-flop with synchronous enable

Library: ieee;

Listing 5.1: D Flip-Flop Without Asynchronous Reset

use ieee.std_logic_1164.all;
entity d_ff is port(
  clk: in std_logic;
  d: in std_logic;
  q: out std_logic
);
end d_ff;

architecture arch of d_ff is
begin
  process(clk)
  begin
    if (clk'event and clk='1') then
      q <= d;
    end if;
  end process;
end arch;

Listing 5.2: D Flip-Flop With Asynchronous Reset

entity d_ff_reset is port(
  clk, reset: in std_logic;
  d: in std_logic;
  q: out std_logic
);
end d_ff_reset;

architecture arch of d_ff_reset is
begin
  process(clk, reset)
  begin
    if (reset='1') then
      q <= '0';
    elsif (clk'event and clk='1') then
      q <= d;
    end if;
  end process;
end arch;

Listing 5.3: D Flip-Flop With Synchronous Enable

library ieee;
use ieee.std_logic_1164.all;
entity d_ff_en is port(
  clk, reset: in std_logic;
  en: in std_logic;
  d: in std_logic;
  q: out std_logic
);
end d_ff_en;

architecture arch of d_ff_en is
begin
  process(clk, reset)
  begin
    if (reset='1') then
      q <= '0';
    elsif (clk'event and clk='1' and en='1') then
      q <= d;
    end if;
  end process;
end arch;

2. Shift Registers

Listing 5.4: N-Bit Free-Running Shift Register

library ieee;
use ieee.std_logic_1164.all;
entity free_run_shift_reg is generic(n: integer := 8);
port(
  clk, reset: in std_logic;
  s_in: in std_logic;
  s_out: out std_logic
);
end free_run_shift_reg;

architecture arch of free_run_shift_reg is
  signal r_reg: std_logic_vector(n-1 downto 0);
  signal r_next: std_logic_vector(n-1 downto 0);
begin
  process(clk, reset)
  begin
    if (reset='1') then
      r_reg <= (others=>'0');
    elsif (clk'event and clk='1') then
      r_reg <= r_next;
    end if;
  end process;

  r_next <= s_in & r_reg(n-1 downto 1);
  s_out <= r_reg(0);
end arch;

Listing 5.5: Universal Shift Register

library ieee;
use ieee.std_logic_1164.all;
entity univ_shift_reg is generic(n: integer := 8);
port(
  clk, reset: in std_logic;
  ctrl: in std_logic_vector(1 downto 0);
  d: in std_logic_vector(n-1 downto 0);
  q: out std_logic_vector(n-1 downto 0)
);
end univ_shift_reg;

architecture arch of univ_shift_reg is
  signal r_reg: std_logic_vector(n-1 downto 0);
begin
  process(clk, reset)
  begin
    if (reset='1') then
      r_reg <= (others=>'0');
    elsif (clk'event and clk='1') then
      case ctrl is
        when "00" => r_reg <= r_reg;
        when "01" => r_reg <= d;
        when "10" => r_reg <= r_reg(n-1 downto 1) & d(0);
        when others => r_reg <= '0' & r_reg(n-1 downto 1);
      end case;
    end if;
  end process;
  q <= r_reg;
end arch;

3. Counters

Listing 5.6: Free-Running Binary Counter

library ieee;
use ieee.std_logic_1164.all;
entity free_run_bin_counter is generic(n: integer := 8);
port(
  clk, reset: in std_logic;
  max_tick: out std_logic;
  q: out std_logic_vector(n-1 downto 0)
);
end free_run_bin_counter;

architecture arch of free_run_bin_counter is
  signal r_reg: unsigned(n-1 downto 0);
begin
  process(clk, reset)
  begin
    if (reset='1') then
      r_reg <= (others=>'0');
    elsif (clk'event and clk='1') then
      r_reg <= r_reg + 1;
    end if;
  end process;
  q <= std_logic_vector(r_reg);
  max_tick <= '1' when r_reg = (2**n - 1) else '0';
end arch;

Listing 5.7: Universal Binary Counter

library ieee;
use ieee.std_logic_1164.all;
entity univ_bin_counter is generic(n: integer := 8);
port(
  clk, reset: in std_logic;
  syn_clr, load, en, up: in std_logic;
  d: in std_logic_vector(n-1 downto 0);
  max_tick, min_tick: out std_logic;
  q: out std_logic_vector(n-1 downto 0)
);
end univ_bin_counter;

architecture arch of univ_bin_counter is
  signal r_reg: unsigned(n-1 downto 0);
  signal r_next: unsigned(n-1 downto 0);
begin
  process(clk, reset)
  begin
    if (reset='1') then
      r_reg <= (others=>'0');
    elsif (clk'event and clk='1') then
      r_reg <= r_next;
    end if;
  end process;

  r_next <= r_reg + 1 when (en='1' and up='1') else
             r_reg - 1 when (en='1' and up='0') else
             r_reg;
  q <= std_logic_vector(r_reg);
  max_tick <= '1' when r_reg = (2**n - 1) else '0';
  min_tick <= '1' when r_reg = '0' else '0';
end arch;

4. Testbenches

Listing 5.8: Testbench for a Universal Binary Counter

library ieee;
use ieee.std_logic_1164.all;
entity bin_counter_tb is
end bin_counter_tb;

architecture arch of bin_counter_tb is
  constant t: time := 20 ns;
  signal clk, reset: std_logic;
  signal syn_clr, load, en, up: std_logic;
  signal d: std_logic_vector(3 downto 0);
  signal max_tick, min_tick: std_logic;
  signal q: std_logic_vector(3 downto 0);
begin
  process
  begin
    clk <= '0';
    wait for t/2;
    clk <= '1';
    wait for t/2;
  end process;

  process
  begin
    reset <= '1';
    wait for t;
    reset <= '0';
    wait;
  end process;

  -- Instantiate the counter unit
  counter_unit: entity work.univ_bin_counter(arch)
  generic map(n => 3)
  port map(clk => clk, reset => reset, syn_clr => syn_clr, load => load, en => en, up => up, d => d,
           max_tick => max_tick, min_tick => min_tick, q => q);
end arch;