Categories
FPGA

FPGA VHDL 7 Segment Multiplexing

Toady we are going to explain how to do time division multiple in VHDL language. This project will display a simple method to do the 7 segment multiplexing in VHDL language for Nexys 3 FPGA development board. To further understand the code you may want to look into our previous FPGA LED blinking example, where we explained how the onboard LED can be accessed in VHDL and Verilog and how we can use the onboard clock to generate the required amount of timing delays. In today’s example we are extending that example code to display numbers on the on board 7 segment displays. Here is the circuit diagram of that Nexys 3 FPGA board.

FGA Circuit diagram for nexys3

As you can see in this diagram that 4 7 segment displays are attached to the Spartan 6 FPGA and you can also check the respective pins in the circuit diagram.

Single Digit up counter in VHDL

First of all let’s look into the single digit 7 segment display counter code in the VHDL which will count from 0 to 9 and only use one digit. This will not do any kind of multiplexing but give you a general idea of what the 7 segment decoder look like when implemented in VHDL.

entity sevensegment_ex01 is
    Port ( anodes : out  STD_LOGIC_VECTOR (3 downto 0);
     clk : in  STD_LOGIC;
           cathods : out  STD_LOGIC_VECTOR (7 downto 0));
end sevensegment_ex01;

architecture Behavioral of sevensegment_ex01 is
 signal digit0 :   std_logic_vector (7 downto 0);
 signal counter : natural range 0 to 9 := 0;
 signal clk_counter : natural range 0 to 50000000 := 0;
 
 
begin

 process(clk)
 begin 
  if rising_edge(clk) then 
   clk_counter <= clk_counter + 1; 
   if clk_counter >= 50000000 then 
     clk_counter <= 0;
     if counter > 8 then 
         counter <= 0;
    else
     counter <= counter +1; 
     end if;
   end if; 
  end if; 
 end process;
 
 
 process(counter)
 begin 
  case counter is 
   when 0 => cathods <= "11000000"; --0
   when 1 => cathods <= "11111001"; --1
   when 2 => cathods <= "10100100"; --2
   when 3 => cathods <= "10110000"; --3
   when 4 => cathods <= "10011001"; --4
   when 5 => cathods <= "10010010"; --5
   when 6 => cathods <= "10000010"; --6
   when 7 => cathods <= "11111000"; --7
   when 8 => cathods <= "10000000"; --8
   when 9 => cathods <= "10010000"; --9
  end case;
 end process;
 
 
 anodes <= "1110";
 --cathods  <=  digit0;

end Behavioral;


Code language: VHDL (vhdl)

7 segment Multiplexing

Now let’s try to extend this code and try to implement a multiplexer. Which could be accomplished by with the process which is clock dependent but this time the clock is very fast. We will provide 1 millisecond clock source to refresh every digit. To generate this clock we will use the on board 100MHz clock input so we need to wait for 10000 clocks. We can achieve this division by adding a signal of type natural range 0 to 10000 :=0; Here is the complete source code.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity sevensegment_ex01 is
    Port ( anodes : out  STD_LOGIC_VECTOR (3 downto 0);
     clk : in  STD_LOGIC;
           cathods : out  STD_LOGIC_VECTOR (7 downto 0));
end sevensegment_ex01;

architecture Behavioral of sevensegment_ex01 is
 signal digit0 :   std_logic_vector (7 downto 0);
 signal anodeval : std_logic_vector (3 downto 0);
 signal counter : natural range 0 to 9 := 0;
 signal clk_counter : natural range 0 to 100000 := 0;
 signal digit_number : natural range 0 to 4 :=0;
 
  
begin

 process(clk)
 begin 
  if rising_edge(clk) then 
   clk_counter <= clk_counter + 1; 
   if clk_counter >= 100000 then 
     clk_counter <= 0;
     digit_number <= digit_number +1;
     if digit_number >=4 then
     digit_number <=0;
     end if; 
   end if; 
  end if; 
 end process;
 
 process(digit_number)
 begin
  case digit_number is
   when 0 =>  anodeval <= "1110";
   when 1 =>  anodeval <= "1101";
   when 2 =>  anodeval <= "1011";
   when 3 =>  anodeval <= "0111";
   when 4 =>  anodeval <= "1111";
  end case;
 end process;
 
 process(digit_number)
 begin
  case digit_number is
   when 0 =>  counter <= 1;
   when 1 =>  counter <= 2;
   when 2 =>  counter <= 3;
   when 3 =>  counter <= 4;
   when 4 =>  counter <= 0;
  end case;
 end process;
-- 
 process(counter)
 begin 
  case counter is 
   when 0 => cathods <= "11000000"; --0
   when 1 => cathods <= "11111001"; --1
   when 2 => cathods <= "10100100"; --2
   when 3 => cathods <= "10110000"; --3
   when 4 => cathods <= "10011001"; --4
   when 5 => cathods <= "10010010"; --5
   when 6 => cathods <= "10000010"; --6
   when 7 => cathods <= "11111000"; --7
   when 8 => cathods <= "10000000"; --8
   when 9 => cathods <= "10010000"; --9
  end case;
 end process;
 
 
 
 anodes <= anodeval;
 --cathods  <=  digit0;

end Behavioral;


Code language: VHDL (vhdl)

Here is the ucf file which describe the on board pins mapping to spartan 6 FPGA.



NET "anodes<0>"  LOC = "N16";
NET "anodes<1>"  LOC = "N15";
NET "anodes<2>"  LOC = "P18";
NET "anodes<3>"  LOC = "P17";

NET "clk" LOC = V10;

NET "cathods<0>"   LOC = "T17" ;
NET "cathods<1>"   LOC = "T18" ;
NET "cathods<2>"   LOC = "U17" ;
NET "cathods<3>"   LOC = "U18" ;
NET "cathods<4>"   LOC = "M14" ;
NET "cathods<5>"   LOC = "N14" ;
NET "cathods<6>"   LOC = "L14" ;
NET "cathods<7>"   LOC = "M13" ;Code language: JavaScript (javascript)

By Abdul Rehman

My name is Abdul Rehman and I love to do Reasearch in Embedded Systems, Artificial Intelligence, Computer Vision and Engineering related fields. With 10+ years of experience in Research and Development field in Embedded systems I touched lot of technologies including Web development, and Mobile Application development. Now with the help of Social Presence, I like to share my knowledge and to document everything I learned and still learning.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.