Tuesday, April 3, 2012

Rotating LED VHDL Lab Code With Intermediate-Sized Sequential Circuit Project Design and Procedures

Rotating LED is an intermediate-sized sequential circuit. Rotating LED lab will utilize seven-segment LED and clock functionality. VHDL language is used to implement this rotating LED logic on Altera DE1 FPGA device using  Altera Quartus design suite.


Project specification: In a seven-segment LED display, a square pattern can be created by enabling the a, b, f, and g segments or the c, d, e, and g segments. We want to design a circuit that circulates the square patterns in the four-digit seven-segment LED display. The circulating pattern could either be clockwise or counter-clockwise depending on the user input. The clockwise circulating pattern is shown above, just to give you an idea how we want to implement our rotating LED circuit logic. The control signals of the circuit can specify the rotation speed, the direction of rotation (i.e., clockwise or counterclockwise), and pause the operation. The rotating LED circuit design must be synchronous. We will use 4 switches for the control signals and 50MHz oscillator for clock from DE1 Altera FPGA board. The input and output signals for rotating LED logic circuit will be as follows:

Inputs:
• clk: 50 MHz clock signal from the DE1 board.
• pa: 1-bit enable signal. The circulation pauses when it is 1.
• cw: 1-bit direction signal. The pattern circulates clockwise when it is 1 and counter
clockwise when it is 0.
• sp: 2-bit speed control:
• 00: each pattern stays 20 ms
• 01: each pattern stays 40 ms
• 10: each pattern stays 80 ms
• 11: each pattern stays 160 ms

Output:
• Four seven-segment LED displays.



Design Procedures: We can divide rotating LED circuit into four segments and finally we can add up a wrapping VHDL code to instantiate all the modules. Lets first go through each module required to do the rotating LED circuit lab with the VHDL code provided:

Counter 1: generate a one-clock pulse (tick1) every 10 ms.


VHDL module Code to generate one clock pulse every 10 ms:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity counter_1 is
   port(
      clk: in std_logic;
      tick1: out std_logic
   );
end counter_1;
architecture arch of counter_1 is
   constant DVSR: integer:=500000;
   signal ms_reg, ms_next: unsigned(18 downto 0);
begin
   -- register
   process(clk)
   begin
      if (clk'event and clk='1') then
         ms_reg <= ms_next;
      end if;
   end process;
   -- next-state logic
   -- 0.01(10ms) sec tick generator: mod-500000
   ms_next <=
      (others=>'0') when ms_reg=DVSR else
      ms_reg + 1;
   tick1 <= '1' when ms_reg=DVSR else '0';
end arch;   



Counter 2: utilizes tick1 pulse and generates a one-clock pulse (tick2) every 20 ms, 40 ms, 80 ms or 160 ms based on the sp input signal.

VHDL module Code to control the speed of rotating LED circuit:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity counter_2 is
   port(
      clk: in std_logic;
tick1: in std_logic;
sp: in std_logic_vector(1 downto 0);
      tick2: out std_logic
   );
end counter_2;
architecture arch of counter_2 is
   signal d1_reg, d0_reg: unsigned(3 downto 0);
   signal d1_next, d0_next: unsigned(3 downto 0);
   signal d1_en, d0_en: std_logic;
   signal d0_tick, tick_20ms, tick_40ms, tick_80ms, tick_160ms: std_logic;
begin
   -- register
   process(clk)
   begin
      if (clk'event and clk='1') then
         d1_reg <= d1_next;
         d0_reg <= d0_next;
      end if;
   end process;
   -- next-state logic
   -- 0.01 sec counter
   d0_en <= '1' when tick1='1' else '0';
   d0_next <=
      "0000" when (d0_en='1' and d0_reg=15) else
      d0_reg + 1 when d0_en='1' else
      d0_reg;
    tick_20ms <= '1' when d0_reg=2 else '0';
tick_40ms <= '1' when d0_reg=4 else '0';
tick_80ms <= '1' when d0_reg=8 else '0';
d0_tick <= '1' when d0_reg=9 else '0';
   -- .1 sec counter
   d1_en <= '1' when tick1='1' and d0_tick='1' else '0';
   d1_next <=
      "0000" when (d1_en='1' and d1_reg=9) else
      d1_reg + 1 when d1_en='1' else
      d1_reg;
   tick_160ms <= '1' when (d1_reg=1 and d0_reg=6) else '0';
   -- output logic
with sp select
      tick2 <=   tick_20ms when "00",
                 tick_40ms when "01",
                 tick_80ms when "10",
                 tick_160ms when others;
end arch;




Counter 3: mod-8 counter that utilizes tick2 pulse and can pause, count up and count down.

VHDL module Code for mod 8 counter to control the direction of rotating LED circuit:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity counter_3 is
   generic(
      N: integer := 3;     -- number of bits
      M: integer := 8      -- mod-M
  );
   port(
      clk: in std_logic;
      tick2, cw, pa: in std_logic;
      q: out std_logic_vector(N-1 downto 0)
   );
end counter_3;
architecture arch of counter_3 is
   signal r_regf, r_reg1, r_reg2: unsigned(N-1 downto 0);
   signal r_nextf, r_next1, r_next2: unsigned(N-1 downto 0);
begin
   -- register
   process(clk,pa)
   begin
      if (clk'event and clk='1' and tick2='1' and pa='0') then
         r_regf <= r_nextf;
         r_reg1 <= r_next1;
         r_reg2 <= r_next2;
end if;
   end process;
   -- next-state logic
r_next1 <= (others=>'0') when r_reg1=(M-1) else
             r_reg1 + 1;
r_next2 <= (others=>'1') when r_reg2=(0) else
             r_reg2 - 1;
r_nextf <= r_next1 when(cw='1') else
 r_next2;
-- output logic
   q <= std_logic_vector(r_regf);
end arch;



Decoding Circuit: A decoding circuit that generates the desired LED patterns.

VHDL module code for decoding rotating LED circuit:

library ieee;
use ieee.std_logic_1164.all;
entity decoder_rotatingLED is
port
(
input: in std_logic_vector(2 downto 0);
en: out std_logic_vector(27 downto 0)
);
end decoder_rotatingLED;
architecture arch of decoder_rotatingLED is
begin
process(input)
begin
case input  is
            when "000" =>   en <= "0011100111111111111111111111";
            when "001" =>   en <= "1111111001110011111111111111";
            when "010" =>   en <= "1111111111111100111001111111";
            when "011" =>   en <= "1111111111111111111110011100";
            when "100" =>   en <= "1111111111111111111110100011";
            when "101" =>   en <= "1111111111111101000111111111";
            when "110" =>   en <= "1111111010001111111111111111";
            when "111" =>   en <= "0100011111111111111111111111";
end case;
end process;
end arch;
Final Wrapping up circuit for rotating LED circuit which will instantiate all the modules defined above(counter1, counter2, counter3, decoding circuit). In Altera Quartus design suite, this final rotatingLED VHDL module will be set as top level entity declaration before compiling.

VHDL module Code for rotatingLED is:


library ieee;
use ieee.std_logic_1164.all;
entity rotatingLED is
port
(
final_clk: in std_logic;
final_pa, final_cw: in std_logic;
final_sp: in std_logic_vector(1 downto 0);
hex3, hex2, hex1, hex0: out std_logic_vector(6 downto 0)
);
end rotatingLED;
architecture arch of rotatingLED is
signal temp0, temp1: std_logic;
signal temp2: std_logic_vector(2 downto 0);
signal cycle: std_logic_vector(27 downto 0);
begin
c1_unit: entity work.counter_1(arch)
port map(clk=>final_clk, tick1=>temp0);
c2_unit: entity work.counter_2(arch)
port map(clk=>final_clk, tick1=>temp0, sp=>final_sp, tick2=>temp1);
c3_unit: entity work.counter_3(arch)
port map(clk=>final_clk, tick2=>temp1, pa=>final_pa, cw=>final_cw, q=>temp2);
decoder_rotatingLED_unit: entity work.decoder_rotatingLED(arch)
port map(input=>temp2, en=>cycle);
hex3 <= cycle(27 downto 21);
hex2 <= cycle(20 downto 14);
hex1 <= cycle(13 downto 7);
hex0 <= cycle(6 downto 0);
end arch;

We will also do the pin assignment for this rotating LED circuit lab as follows:
From To Assignment Name Value Enabled
     final_pa Location PIN_L22 Yes
     final_cw Location PIN_L21 Yes
     final_sp[0] Location PIN_M22 Yes
     final_sp[1] Location PIN_V12 Yes
     final_clk Location PIN_L1 Yes
hex0[0] Location PIN_J2 Yes
hex0[1] Location PIN_J1 Yes
hex0[2] Location PIN_H2 Yes
hex0[3] Location PIN_H1 Yes
hex0[4] Location PIN_F2 Yes
hex0[5] Location PIN_F1 Yes
hex0[6] Location PIN_E2 Yes
hex1[0] Location PIN_E1 Yes
hex1[1] Location PIN_H6 Yes
hex1[2] Location PIN_H5 Yes
hex1[3] Location PIN_H4 Yes
hex1[4] Location PIN_G3 Yes
hex1[5] Location PIN_D2 Yes
hex1[6] Location PIN_D1 Yes
hex2[0] Location PIN_G5 Yes
hex2[1] Location PIN_G6 Yes
hex2[2] Location PIN_C2 Yes
hex2[3] Location PIN_C1 Yes
hex2[4] Location PIN_E3 Yes
hex2[5] Location PIN_E4 Yes
hex2[6] Location PIN_D3 Yes
hex3[0] Location PIN_F4 Yes
hex3[1] Location PIN_D5 Yes
hex3[2] Location PIN_D6 Yes
hex3[3] Location PIN_J4 Yes
hex3[4] Location PIN_L8 Yes
hex3[5] Location PIN_F3 Yes
hex3[6] Location PIN_D4 Yes

Please leave your feedback to improve the quality of the code on this site. Check out our selection VHDL related posts and lab codes.

4 comments:

This comment has been removed by the author.
This comment has been removed by the author.

After typing this code it seems as though our clock does not count up. Is there a reason for this?

After executing this code output is UUUUU

Post a Comment