VHDL: BCD to 7-segment display converter

THIS BLOG POST WAS UPDATED ON 4th Mar 2024!

    7-segment displays are commonly used in FPGA (Field-Programmable Gate Array) boards for displaying numeric and sometimes alphanumeric information. These displays consist of seven individual LED segments arranged in a pattern that can display numerals from 0 to 9, as well as some letters such as A-F for hexadecimal displays. 
Typical FPGA board with 7 segment display

    To show a certain character using the 7 segment display, you need to lit up the corresponding segments. This is done by not passing a voltage to it, basically driving it with a '0' signal in VHDL.    

The following image shows how the numbers from 0 to 9 can be displayed using a 7 segment display.

 

The following VHDL code can be used to convert bcd digits into 7 bit std_logic_vector signals which can be used to show the correct digits on the display piece. Note that, a in the above picture corresponds to MSB of segment7 and g corresponds to LSB of segment7.

VHDL Entity:


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity seven_segment_decoder is
port (
    bcd : in unsigned(3 downto 0);  --BCD input
    -- 'a' corresponds to MSB of segment7 and g corresponds to LSB of segment7.
    segment7 : out std_logic_vector(6 downto 0)  -- 7 bit decoded output.
);
end seven_segment_decoder;

architecture Behavioral of seven_segment_decoder is

begin

process (bcd)
BEGIN
case bcd is
    when "0000"=> segment7 <="0000001";  -- '0'
    when "0001"=> segment7 <="1001111";  -- '1'
    when "0010"=> segment7 <="0010010";  -- '2'
    when "0011"=> segment7 <="0000110";  -- '3'
    when "0100"=> segment7 <="1001100";  -- '4'
    when "0101"=> segment7 <="0100100";  -- '5'
    when "0110"=> segment7 <="0100000";  -- '6'
    when "0111"=> segment7 <="0001111";  -- '7'
    when "1000"=> segment7 <="0000000";  -- '8'
    when "1001"=> segment7 <="0000100";  -- '9'
    --nothing is displayed when a number more than 9 is given as input.
    when others=> segment7 <="1111111";
end case;
end process;

end Behavioral;

    If you want a decimal number of higher than 9 to be displayed using this code, then convert the decimal number into BCD and then instantiate this module for each digit in the BCD code.

Testbench:

Here is a sample test bench code for this module:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

ENTITY tb_seg7_decoder IS
END tb_seg7_decoder;

ARCHITECTURE behavior OF tb_seg7_decoder IS

signal bcd : unsigned(3 downto 0) := (others => '0');
signal segment7 : std_logic_vector(6 downto 0);

BEGIN

--entity port mapping. Usiong 
uut: entity work.seven_segment_decoder PORT MAP 
    (bcd => bcd,
    segment7 => segment7); 

stim_proc: process
begin      
    -- apply an input bcd digit and wait for 100 ns
    -- so that we can check the output in the waveform.         
    for i in 0 to 9 loop
        bcd <= to_unsigned(i,4);
	wait for 100 ns;
    end loop;
end process;

END;

Simulation waveform:

The codes were simulated using modelsim and the following simulation waveform was obtained.


Post a Comment

5 Comments

  1. hello.. can you pls post a test bench for this code.. tnx...

    ReplyDelete
  2. @Alfred : I have modified the post including the test bench.Hope that helps..

    ReplyDelete
  3. thank you, it is so useful for me.
    Can you show me, how to control a animation on vga using keyboard in vhdl

    ReplyDelete
  4. Hi, I'm trying to implement the sum of two numbers with 5 bits and show in two digits SSD, but with no success, do you have any idea how to do this?

    I had success with decimal counter until 99, but how make this work whit the sum, I don't know.

    Thanks

    ReplyDelete