- 2070 Bhadra · 8 marks
BCD counter 0-9999 on seven segment VHDL
Short answer
A 4-digit BCD counter increments on a slow tick (e.g. one second). Digits are multiplexed on a 7-segment display by scanning with a fast clock. The design uses tick and scan dividers, BCD to seven-segment decoding, and active-low segment and digit enables.
Write the code for BCD counter to display 0 to 9999 in seven segment using VHDL.
Design
- A 4-digit BCD counter (0000 to 9999) is stored as four 4-bit digits. A slow tick (one per second) increments the units digit; each digit rolls from 9 to 0 and carries into the next; 9999 wraps to 0000.
- A seven-segment display (assumed common anode, so segments and digit enables are active low, as on common FPGA boards) shows the four digits. The digits share the segment lines and are scanned (multiplexed) one at a time at about 1 kHz, so all appear lit.
- Generics
TICK_DIVandSCAN_DIVgive the number of clock cycles per count and per digit (default for a 50 MHz clock), and can be made small for simulation.
clk -> [tick divider] -> [4-digit BCD counter]
| digit(0..3)
v
clk -> [scan div] -> [sel] -> [4:1 mux] -> [7-seg] -> seg
+--> [2-to-4 decoder] ---------> an
VHDL code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bcd_counter_7seg is
generic (
TICK_DIV : positive := 50_000_000; -- clocks per count step (1 s at 50 MHz)
SCAN_DIV : positive := 50_000 -- clocks per digit (1 ms at 50 MHz)
);
port (
clk : in std_logic;
rst : in std_logic; -- active high
seg : out std_logic_vector(6 downto 0); -- g f e d c b a, active low
an : out std_logic_vector(3 downto 0) -- digit enable, active low
);
end entity bcd_counter_7seg;
architecture rtl of bcd_counter_7seg is
type bcd_array is array (0 to 3) of unsigned(3 downto 0);
signal digit : bcd_array := (others => (others => '0')); -- 0=units ... 3=thousands
signal tick_cnt : integer range 0 to TICK_DIV - 1 := 0;
signal scan_cnt : integer range 0 to SCAN_DIV - 1 := 0;
signal sel : unsigned(1 downto 0) := (others => '0'); -- digit being displayed
signal value : unsigned(3 downto 0);
-- BCD to seven segment (active low, bit order g f e d c b a)
function to_seg(d : unsigned(3 downto 0)) return std_logic_vector is
begin
case to_integer(d) is
when 0 => return "1000000";
when 1 => return "1111001";
when 2 => return "0100100";
when 3 => return "0110000";
when 4 => return "0011001";
when 5 => return "0010010";
when 6 => return "0000010";
when 7 => return "1111000";
when 8 => return "0000000";
when 9 => return "0010000";
when others => return "1111111"; -- blank
end case;
end function;
begin
-- 1) BCD counter 0000 .. 9999
count_proc : process (clk, rst)
begin
if rst = '1' then
digit <= (others => (others => '0'));
tick_cnt <= 0;
elsif rising_edge(clk) then
if tick_cnt = TICK_DIV - 1 then
tick_cnt <= 0;
if digit(0) /= 9 then
digit(0) <= digit(0) + 1;
else
digit(0) <= (others => '0');
if digit(1) /= 9 then
digit(1) <= digit(1) + 1;
else
digit(1) <= (others => '0');
if digit(2) /= 9 then
digit(2) <= digit(2) + 1;
else
digit(2) <= (others => '0');
if digit(3) /= 9 then
digit(3) <= digit(3) + 1;
else
digit(3) <= (others => '0'); -- 9999 -> 0000
end if;
end if;
end if;
end if;
else
tick_cnt <= tick_cnt + 1;
end if;
end if;
end process;
-- 2) refresh: show one digit at a time
scan_proc : process (clk, rst)
begin
if rst = '1' then
scan_cnt <= 0;
sel <= (others => '0');
elsif rising_edge(clk) then
if scan_cnt = SCAN_DIV - 1 then
scan_cnt <= 0;
sel <= sel + 1;
else
scan_cnt <= scan_cnt + 1;
end if;
end if;
end process;
value <= digit(to_integer(sel));
seg <= to_seg(value);
an <= "1110" when sel = "00" else
"1101" when sel = "01" else
"1011" when sel = "10" else
"0111";
end architecture rtl;
The code was analysed with GHDL and simulated with small generics: after 123 count steps the scanned digits were 3 (units), 2 (tens), 1 (hundreds), 0 (thousands), showing 0123.
✓ Answer checked by Claude Opus 5.5 (high effort)
Related questions
- Seven segment display and clock counter · Embedded System, chapter 9
- Display 0 to 9 on seven segment · Embedded System, chapter 9 · asked 2×
- Display 99 to 00 on seven segment · Embedded System, chapter 9
- BCD-to-7-segment decoder; frequency counter · Digital Logic, chapter 11
- BCD-to-seven-segment decoder, segments a and e · Digital Logic, chapter 4
- DEMUX vs decoder; seven-segment "b" segment · Digital Logic, chapter 4
- Seven-segment "a" segment using NOR gates · Digital Logic, chapter 4