← Back to list

VHDL Part 2 — Building a Multi-Digit 7-Segment Clock in VHDL (Simulation First)

Goal

Preston Hager · 2026-05-06 03:13 · 0 claps · 2.0 min read
#vhdl
Open on Medium ↗

VHDL Part 2 — Building a Multi-Digit 7-Segment Clock in VHDL (Simulation First)

Goal

Build a simulated digital clock:

MM:SS → 4-digit 7-segment display

Pipeline:

Clock → Divider → Counters → Decoder → Display

Step 1 — Clock Divider (Simulation-Friendly)

entity clock_divider is
    Port ( clk_in : in STD_LOGIC;
           clk_out : out STD_LOGIC );
end;

architecture Behavioral of clock_divider is
signal count : integer := 0;
signal tmp : STD_LOGIC := '0';
begin
process(clk_in)
begin
    if rising_edge(clk_in) then
        count <= count + 1;
        if count = 10 then  -- fast for simulation
            tmp <= not tmp;
            count <= 0;
        end if;
    end if;
end process;
clk_out <= tmp;
end;

Step 2 — Modulo Counters

0–9 Counter

entity counter_10 is
    Port ( clk : in STD_LOGIC;
           value : out integer range 0 to 9 );
end;

architecture Behavioral of counter_10 is
signal cnt : integer := 0;
begin
process(clk)
begin
    if rising_edge(clk) then
        if cnt = 9 then
            cnt <= 0;
        else
            cnt <= cnt + 1;
        end if;
    end if;
end process;
value <= cnt;
end;

0–5 Counter (for seconds/minutes tens)

entity counter_6 is
    Port ( clk : in STD_LOGIC;
           value : out integer range 0 to 5 );
end;

architecture Behavioral of counter_6 is
signal cnt : integer := 0;
begin
process(clk)
begin
    if rising_edge(clk) then
        if cnt = 5 then
            cnt <= 0;
        else
            cnt <= cnt + 1;
        end if;
    end if;
end process;
value <= cnt;
end;

Step 3–7-Segment Decoder

entity decoder is
    Port ( digit : in integer range 0 to 9;
           seg : out STD_LOGIC_VECTOR(6 downto 0));
end;

architecture Behavioral of decoder is
begin
process(digit)
begin
    case digit is
        when 0 => seg <= "1000000";
        when 1 => seg <= "1111001";
        when 2 => seg <= "0100100";
        when 3 => seg <= "0110000";
        when 4 => seg <= "0011001";
        when 5 => seg <= "0010010";
        when 6 => seg <= "0000010";
        when 7 => seg <= "1111000";
        when 8 => seg <= "0000000";
        when 9 => seg <= "0010000";
        when others => seg <= "1111111";
    end case;
end process;
end;

Step 4 — Top-Level Clock System

Conceptually:

seconds_ones → 0–9
seconds_tens → 0–5
minutes_ones → 0–9
minutes_tens → 0–5

Each counter cascades (carry behavior).

Step 5 — Testbench (System-Level)

You simulate time progression, not real-time:

process
begin
    while true loop
        clk <= '0'; wait for 1 ns;
        clk <= '1'; wait for 1 ns;
    end loop;
end process;

Step 6 — Simulating the Display

GHDL doesn’t “draw” a 7-segment display.

Instead:

  • Inspect seg[6:0] in GTKWave
  • Verify transitions match expected digits

Optional — Build a Simple Visualizer

If you want an actual display:

  • Parse .vcd in Python
  • Render ASCII 7-segment output

Example concept:

 _ 
| |
|_|

Step 7 — Compile and Run

ghdl -a *.vhd
ghdl -e top_tb
ghdl -r top_tb --vcd=clock.vcd
gtkwave clock.vcd

What You Just Built

You now have:

  • A clock domain ✔
  • Cascading counters ✔
  • A decoding layer ✔
  • A display interface ✔

This is already:

  • A synchronous digital system
  • A multi-module hardware design
  • Structurally similar to CPU subsystems

메타데이터
post_id
8bb8b60f3893
slug
vhdl-part-2-building-a-multi-digit-7-segment-clock-in-vhdl-simulation-first-8bb8b60f3893
url
https://medium.com/@prestonhager/vhdl-part-2-building-a-multi-digit-7-segment-clock-in-vhdl-simulation-first-8bb8b60f3893
canonical_url
https://medium.com/@prestonhager/vhdl-part-2-building-a-multi-digit-7-segment-clock-in-vhdl-simulation-first-8bb8b60f3893
author_url
https://medium.com/@prestonhager
status
ok
fetched_at
2026-07-10 19:45:50