Sequential Logic

D flip-flops, registers, counters — the memory elements of digital logic.

From Combinational to Sequential

Combinational logic has no memory. To store state, we use memory elements synchronized on a clock.

Synchronous circuit: Inputs → Combinational Logic → Registers → Outputs (with current state feedback)

Image à ajouter

This model is the foundation of every synchronous digital circuit.


The D Flip-Flop

The D flip-flop is the fundamental memory element.

Behavior

EventAction
Rising edge of CLKQ ← D
Between edgesQ retains its value
RST active (synchronous)Q ← 0 on next edge
-- Simple D flip-flop
process(i_clk)
begin
  if rising_edge(i_clk) then
    r_q <= i_d;
  end if;
end process;

D Flip-Flop with Synchronous Reset and Enable

process(i_clk)
begin
  if rising_edge(i_clk) then
    if i_rst = '1' then
      r_q <= '0';
    elsif i_en = '1' then
      r_q <= i_d;
    end if;
  end if;
end process;

Registers

A register is a group of N D flip-flops sharing the same clock — stores N bits simultaneously.

Simple N-bit Register

entity register_8bit is
  port (
    i_clk  : in  std_logic;
    i_rst  : in  std_logic;
    i_en   : in  std_logic;
    i_data : in  std_logic_vector(7 downto 0);
    o_data : out std_logic_vector(7 downto 0)
  );
end entity register_8bit;
 
architecture rtl of register_8bit is
  signal r_data : std_logic_vector(7 downto 0);
begin
  process(i_clk)
  begin
    if rising_edge(i_clk) then
      if i_rst = '1' then
        r_data <= (others => '0');
      elsif i_en = '1' then
        r_data <= i_data;
      end if;
    end if;
  end process;
 
  o_data <= r_data;
end architecture register_8bit;

Shift Register

architecture rtl of shift_reg is
  signal r_shift : std_logic_vector(7 downto 0);
begin
  process(i_clk)
  begin
    if rising_edge(i_clk) then
      if i_rst = '1' then
        r_shift <= (others => '0');
      else
        -- Right shift, serial input on MSB
        r_shift <= i_serial & r_shift(7 downto 1);
      end if;
    end if;
  end process;
 
  o_parallel <= r_shift;         -- parallel output
  o_serial   <= r_shift(0);      -- serial output
end architecture rtl;

Usage: serial-to-parallel conversion (UART, SPI), N-cycle delay.


Counters

Simple Binary Counter

architecture rtl of counter is
  signal r_count : unsigned(7 downto 0);
begin
  process(i_clk)
  begin
    if rising_edge(i_clk) then
      if i_rst = '1' then
        r_count <= (others => '0');
      else
        r_count <= r_count + 1;  -- naturally overflows: 255 → 0
      end if;
    end if;
  end process;
 
  o_count <= std_logic_vector(r_count);
end architecture rtl;

Counter with Limit (Modulo N)

architecture rtl of counter_mod is
  constant c_MAX : integer := 99;  -- counts 0 to 99
 
  signal r_count : integer range 0 to c_MAX;
begin
  process(i_clk)
  begin
    if rising_edge(i_clk) then
      if i_rst = '1' then
        r_count <= 0;
      elsif r_count = c_MAX then
        r_count <= 0;
        o_tick  <= '1';   -- overflow pulse
      else
        r_count <= r_count + 1;
        o_tick  <= '0';
      end if;
    end if;
  end process;
end architecture rtl;

Up/Down Counter

process(i_clk)
begin
  if rising_edge(i_clk) then
    if i_rst = '1' then
      r_count <= (others => '0');
    elsif i_up = '1' then
      r_count <= r_count + 1;
    elsif i_down = '1' then
      r_count <= r_count - 1;
    end if;
  end if;
end process;

Clock Domains and Synchronization

When data crosses different clock domains (CDC — Clock Domain Crossing), metastability issues can occur.

The standard solution: the double-flop synchronizer

-- 2-stage synchronizer for a 1-bit signal
signal r_sync1, r_sync2 : std_logic;
 
process(i_clk_dst)
begin
  if rising_edge(i_clk_dst) then
    r_sync1 <= i_signal_src;  -- first register: may be metastable
    r_sync2 <= r_sync1;       -- second register: stable with high probability
  end if;
end process;
 
o_signal_dst <= r_sync2;

The first register may enter a metastable state, but the second cycle gives it time to resolve.

Rule: never directly use a signal from another clock domain without a synchronizer.