INTRODUCTION

In most digital systems, you will need to display the output of your chip (i.e. clock, calculation results) on an external hardware. One conventional method of doing this is using an array of 7-segment displays. This documentation provides the complete hardware schematic and VHDL code required to implement and array of 7-segments displays in your design project.
 
 

DESIGN BASICS

Two kinds of 7-segment displays is commonly available; common anode and common cathode.  This application note uses the MAN74A common cathode display (available from Morris Locker at CEB 355). Each 7 segment display contains 7 input data pins (1 for each segments) and 1  enable pin.
 
 
  
 

To minimize the number I/O pins needed to control an array of displays, all the 7-segment display will share a common 7-bit data bus. When the data for a particular 7-segment-display is valid on the data bus, the enable signal for that display would be pulled "low", thus displaying the data there. Thus, timing a critical consideration here to ensure that proper information is displayed on each location.

Using this method, the amount of I/O pins needed to implement an array of N 7-segment displays is ( N + 7 ). The VHDL code and hardware needed to support this implementation is given below.
 
 

VHDL CODE

This code, used in our design, cycles through an array of nine 7-segment displays in 1/ (9*clk) seconds. At each state, this entity sends a data to all the 9 seven-segment displays and enables the correct seven-segment to display the data. 4 bits of data (1 digit) is displayed at one time. Upon cycling through the 9 displays (9 states), it returns to the original state and the sequence is repeated. It calls the entity decoder_7seg which is a BCD to 7-segment converter.
 

-- OUTPUT_7SEG_DISPLAY --
library ieee;
use ieee.std_logic_1164.all;

entity output_7seg_display is
  port (
    clk : in std_logic;                             &nb sp;                                    -- clock
    data : in std_logic_vector(35 downto 0);                            -- 36 bits of data  (9 digits) for the 9 displays
    data_7display : out std_logic_vector(6 downto 0);            -- 7-segment code for one digit to be displayed
    enable_7display : out std_logic_vector(8 downto 0)          -- enables the correct 7-segment to display the data
  );
end output_7seg_display;
 

architecture behaviour of output_7seg_display is

  component decoder_7seg
    port (
      input : in std_logic_vector(3 downto 0);
      led : out std_logic_vector(6 downto 0)
    );
  end component;

  type state_type is (ctime1, ctime2, ctime3, ctime4, slot1, c1, c2, c3, c4);
  signal state: state_type;
  signal bcdcode : std_logic_vector(3 downto 0);

begin

  dec1 : decoder_7seg
    port map (input => bcdcode,
              led => data_7display);

  fsm : process
  begin
  wait until rising_edge(clk);
  case state is
      when ctime1 =>
        bcdcode <= data(35 downto 32);                                                     -- data for the 1st display
        enable_7display <= "000000001";                                      ;            -- enable the 1st display
        state <= ctime2;
 
      when ctime2 =>
        bcdcode <= data(31 downto 28);                                                     -- data for 2nd display
        enable_7display(1) <= '1';                                     &nbs p;                        -- enable the 2nd display            
        enable_7display(0) <= '0';
        state <= ctime3;

      when ctime3 =>
        bcdcode <= data(27 downto 24);                                                      -- data for 3rd display   
        enable_7display(2) <= '1';                                     &nbs p;                        -- enable the 3rd display
        enable_7display(1) <= '0';
        state <= ctime4;

      when ctime4 =>
        bcdcode <= data(23 downto 20);
        enable_7display(3) <= '1';                                     &nbs p;                         -- "000001000"
        enable_7display(2) <= '0';
        state <= slot1;

      when slot1 =>
        bcdcode <= data(19 downto 16);
        enable_7display(4) <= '1';                                     &nbs p;                          -- "000010000"
        enable_7display(3) <= '0';

      when c1 =>
        bcdcode <= data(15 downto 12);
        enable_7display(5) <= '1';                                     &nbs p;                           -- "000100000"
        enable_7display(4) <= '0';
        state <= c2;

      when c2 =>
        bcdcode <= data(11 downto 8);
        enable_7display(6) <= '1';                                     &nbs p;                           -- "001000000"
        enable_7display(5) <= '0';
        state <= c3;

      when c3 =>
        bcdcode <= data(7 downto 4);
        enable_7display(7) <= '1';                                     &nbs p;                            -- "010000000"
        enable_7display(6) <= '0';
        state <= c4;

      when c4 =>
        bcdcode <= data(3 downto 0);
        enable_7display(8) <= '1';                                     &nbs p;                              -- "100000000"
        enable_7display(7) <= '0';
        state <= ctime1;

    end case;
  end process fsm;
end behaviour;
 
 

-- DECODER_7SEG --
library ieee;
use ieee.std_logic_1164.all;

-- The entity is obtained from past project "Thermostat".
-- Modification: one more state is added to display '-' at the LED,
--               it means undefined input
--
-- This entity decodes binary input to seven-segment LED input
--
-- input: A binary number which has the range from "0000" to "1001,
--   i.e. 0 to 9.
-- led: 7-bit output for the 7-bit LED segments.
--
-- default output: '-' sign on the seven-segment LED.

entity decoder_7seg is
 port (
  input: in std_logic_vector(3 downto 0);
  led: out std_logic_vector(6 downto 0)
 );
end decoder_7seg;

architecture behaviour of decoder_7seg is
begin
 decode : process(input)
 
begin
 if input = "0000" then
   led     <= '1111110';
 
  elsif input = "0001" then
   led <= '0110000';

  elsif input = "0010" then
   led <= '1101101';

  elsif input = "0011" then
   led <= '1111001';
 
  elsif input = "0100" then
   led <= '0110011';

  elsif input = "0101" then
   led <= '1011011';

  elsif input = "0110" then
   led <= '0011111';

  elsif input = "0111" then
   led <= '1110000';

  elsif input = "1000" then
   led <= '1111111';

  elsif input = "1001" then
   led <= '1110011';

  else
   led <= '0000001';
 
  end if;
 end process decode;
end behaviour;
 
 

Application :
To use this code, copy both the output_7seg_display and decoder_7seg entity to your home directory and compile them. Then, simply instantiate this entity and map the data to be dsiplayed to the data port. An illustration is given below.

                                     out_7display : component output_7seg_display
                                     port map (clk => clk,
                                     &nbs p;                data => DATA,
                                  ;                 -- DATA is the name of the signal
                                     &nbs p;            -- that contains the BCD code to be displayed
                                  ;                     data_7display => data_7display,
                                     &nbs p;                enable_7display => enable_7display);
 
 
A larger array could be used, but due to timing considerations, we do not recommend using more than 10 displays for each module, due to timing considerations. To change the array size, simply change the size of the data input and the number of states respectively.
 
 
 

HARDWARE

A sample hardware schematic connecting 2 MAN74A to an FPGA is given below.
 
 

 
 
 

The  100 ohm resistors is used to limit the current flow to 35 mA. Adjust the resistor correspondingly based on the maximum current sourced by the FPGA. 
 
The clock frequency used in our design was 3.125 MHz. However, a slower clock could be used but keep in mind that the minimum refresh rate for each 7-segment display is 30 times in one second to avoid any flickering.
 

Application :
Hook up the hardware based in the building block given above. Choose an appropriate clock freqeuncy. If the display becomes unstable, try increasing the limiting resistor value. This is probably because the hardware is drawing too much current from the FPGA. On the other hand, if the display is too dim, try putting more current through.
 



Last Update: April 9, 1998
By Allen Ong, Yat Lai, Ritchie Poon
email: apkong@ee.ualberta.ca