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:
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