3.3 STEP 3: A 7-Segment Display Driver

3.3.1 Synopsis

As the data has to appear on a 7-segment display it is not sufficient just to multiplex the incoming signals. The information also has to be transformed from a binary representation into a vector of seven driver signals, one per display element. In order to enhance the readability of the VHDL code, constants should be used to represent the various numbers, i.e.

 
constant SEG_8 : std_ulogic_vector(6 downto 0):= "1111111";
 

The package P_DISPLAY contains the definitions SEG_0 till SEG_9. They define which segment to drive for which number. The additional definition SEG_E can be used, if an error occurs and should be assigned to the number 10.

The new design shall be called DISP_DRV and provides basically the same functionality as the DISP_MUX module. The main difference is that the output signal is now called DISPLAY and its width is now seven bits in order to drive the 7-segment display. The former output port DISPLAY_PHOTO will be used as an internal signal from now on. This is necessary, because the input signals can not be multiplexed directly to the new output signal DISPLAY since they are of a different data type.

The following figure shows the block diagram of the new design.

 

 

The display driver

 

3.3.2 Implementation

The display driver code

library ieee;
use ieee.std_logic_1164.all;
use work.P_DISPLAY.all;

entity DISP_DRV is
  port(ERROR      : in  std_ulogic;
       SHOW_TIME  : in  std_ulogic;
       NO_PICS : in  T_DIGITS;
       EXP_TIME : in  T_DIGITS;
       DISPLAY : out T_DISPLAY);
end DISP_DRV;


architecture RTL of DISP_DRV is
  signal DISP_PHOTO : T_DIGITS;
begin

  DISP_MUX:process (SHOW_TIME, ERROR,
                    EXP_TIME, NO_PICS)
  begin
    if ERROR = '1' then
      DISP_PHOTO <= 10;
    elsif SHOW_TIME = '0' then
      DISP_PHOTO <= NO_PICS;
    else
      DISP_PHOTO <= EXP_TIME;
    end if;
  end process DISP_MUX;

  DECODE: process (DISP_PHOTO)
  begin
    case DISP_PHOTO is
      when 0     => DISPLAY <= SEG_0;
      when 1     => DISPLAY <= SEG_1;
      when 2     => DISPLAY <= SEG_2;
      when 3     => DISPLAY <= SEG_3;
      when 4     => DISPLAY <= SEG_4;
      when 5     => DISPLAY <= SEG_5;
      when 6     => DISPLAY <= SEG_6;
      when 7     => DISPLAY <= SEG_7;
      when 8     => DISPLAY <= SEG_8;
      when 9     => DISPLAY <= SEG_9;
      when others => DISPLAY <= SEG_E;
    end case;
  end process DECODE;
end RTL;
  • Include the declarations from the
    P_DISPLAY package. The library
    WORK is always known and need not
    be declared.
  • User defined data types are used for
    the data ports now.



 
  • An internal signal is needed to link the
    two processes together.
  • The process label is used to enhance
    readability as two processes are
    present in this architecture.
  • Instead of a separate if-statement (as
    in the previous example) an if-elsif-
    else construct is used here.



 
  • The decoder is activated whenever the
    multiplexer changes its output.
  • As there does not exist a priority for
    the different values of DISP_PHOTO,
    a case-statement is used to map the
    integer value to the bit vector.
  • Only the values 0-9 will be displayed
    as digits. In all other cases the user
    will get an 'E', indicating an error.