University of Kufa
Faculty of Engineering
Department of Electronic and Communications Engineering
RGB Generator Using VHDL
By
Ameer Khudhur Abd-AlBaqi
M.S.c Student
ECE Department
30 / 11 / 2023
Content
-Introduction
-Procedures
-Implementation and Results
- Applications
-Appendix
Introduction
RGB components are widely used in today’s devices, one reason is
that they are attractive because of their beautiful colors, control of
such components requires a Microcontroller in most cases, which
in turn uses PWM signal in order to produce analog output from
digital input (Variations in Duty Cycle). This approach could be
expensive for controlling small components.
Procedures
The Most basic RGB component is the RGB LED shown in figure
(1), RGB LED stands for Red, Green, Blue Light Emitting Diode.
It's a type of LED that can emit light in multiple colors, making
RGB LEDs popular in various applications like lighting, displays,
and electronic devices. It consists of 3 anodes and a cathode
(common cathode type) the operation is simple, each of the 3
anodes will be connected to digital high (usually 5V or 3.3V )
while cathode is connected the ground.
Figure.(1) RGB LED.
For anodes, each pin will be at maximum intensity when digital
high is supplied this means we cannot get some colors that require
variations in intensities, only colors that require a combination of
maximum intensities is available, since we have 3 anodes then: 2^3
= 8 Possible colors as shown in Table.(1).
R G B LED
0 0 0 (Off)
0 0 1 Blue
0 1 0 Green
0 1 1 Cyan
1 0 0 Red
1 0 1 Magenta
1 1 0 Yellow
1 1 1 White
Table.(1). Possible colors
Our procedure is to cycle through these possible colors, starting
from cold colors (Blue, Cyan …) toward the hot colors (Red,
Yellow…) With an interval of 1 Second for each color:
Figure.(2) State Diagram.
As we can see from Figure.(2), our FSM is Moore Model which
means that the output depends only on the present state:
Input to FSM: One second interval
Number of States: 8 States
Number of State Transitions : 16 State Transition
Output from FSM: 3-Bit rgb
Implementation and Results
FSM is a combination of sequential and combinational circuits; the
default state here is “off” which produces the output ‘000’ that
means the LED is turned off. A very important aspect of the code
is the counter that is used to make an interval between state
transitions, this counter should produce a digital high whenever 1
second is counted so that this output is used to control state
transitions. Assuming 100 MHz Clock signal is used here, the time
required for one clock signal (period) is 0.00000001 second then
the counter should count to 100000000 to achieve delay of 1
second and produce an output (one_seceond = ‘1’) and resets.
Figure.(3) Netlist RTL Viewer.
To test the results, we tried to simulate the code with the counter
but since the simulation waveform editor in Quartus can only show
output for 100 μs maximum and that is too far from 1 second, so
we cannot simulate the code with this interval, the simulation will
be done using a counter of 0.1 μs instead as an input to the FSM
(same code but different time count, see Figure.(5)) and we can
subdivide the code to two codes (the complete code with the
counter of 1 second) and (the code with the counter of 0.1 μs, see
Appendix).
Figure.(4) Simulation waveform editor (University Program VWF with
button instead of counter).
Figure.(5) Simulation waveform editor (University Program VWF for 0.1 μs
interval).
Applications
1-RGB LED Strip: an array of RGB LEDs all connected to the
same source that produces a wide variety of colors used for
decoration.
Figure.(6) RGB LED Strip.
2-RGB LED Matrix: A display panel made up of individual RGB
LEDs arranged in a specific grid, allowing for dynamic and vibrant
visual displays. These matrices are often used in electronic
projects, digital signage, and various lighting applications.
Figure.(7) RGB LED Matrix.
Appendix
Complete Code for RGB Generator (1 Second Interval):
-- RGB_Generator entity--
library ieee;
use ieee.std_logic_1164.all;
entity RGB_Gen is
Port ( clk : in std_logic;
rst : in std_logic;
rgb : out std_logic_vector(2 downto 0));
end RGB_Gen;
architecture first of RGB_Gen is
component counter IS
PORT ( clk : IN STD_LOGIC; -- clk should be 100 Mhz
rst : IN STD_LOGIC;
one_second : OUT STD_LOGIC);
END component;
type state_type is (off, Blue, Green, Cyan, Red, Magneta, Yellow, White);
signal state, next_state: state_type;
signal one_second : std_logic;
begin
count : counter
port map (clk => clk, rst=>rst, one_second => one_second);
state_assignment: process (clk) is
begin
if rising_edge(clk) then
if (rst = '1') then
state <= off;
else
state <= next_state;
end if;
end if;
end process state_assignment;
fsm_process: process (state, clk) is
begin
case state is
when off =>
if one_second='1' then next_state<=Blue;
else next_state <= state; end if;
when Blue =>
if one_second='1' then next_state<=Cyan;
else next_state <= state; end if;
when Cyan =>
if one_second='1' then next_state<=Green;
else next_state <= state; end if;
when Green =>
if one_second='1' then next_state<=White;
else next_state <= state; end if;
when White =>
if one_second='1' then next_state<=Yellow;
else next_state <= state; end if;
when Yellow =>
if one_second='1' then next_state<=Red;
else next_state <= state; end if;
when Red =>
if one_second='1' then next_state<=Magneta;
else next_state <= state; end if;
when Magneta =>
if one_second='1' then next_state<=off;
else next_state <= state; end if;
end case;
end process fsm_process;
rgb <= "000" when state = off else
"001" when state = Blue else
"011" when state = Cyan else
"010" when state = Green else
"111" when state = White else
"110" when state = Yellow else
"100" when state = Red else
"101" when state = Magneta else
"000";
end first;
-------Counter Entity-----------
library ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY counter IS
PORT ( clk : IN STD_LOGIC; -- clk should be 100 Mhz
rst : IN STD_LOGIC;
one_second : OUT STD_LOGIC);
END counter;
ARCHITECTURE second of counter is
signal counter : unsigned (26 downto 0); -- 134,217,728 * 1/100 Mhz =
1.34217728 second
BEGIN
count_one_sec : process (clk)
begin
if rising_edge(clk) then
if (rst = '1') then
counter <= (others => '0');
else
if (counter = 100000000) then
counter <= (others => '0');
else
counter <= (counter + 1);
end if;
end if;
end if;
end process count_one_sec;
one_second <= '1' when (counter=100000000) else '0';
end second;
--------------------------------------------------------------------------------------------
Complete Code for RGB Generator (0.1 μs Interval):
-- RGB_Generator entity--
library ieee;
use ieee.std_logic_1164.all;
entity RGB_Gen is
Port ( clk : in std_logic;
rst : in std_logic;
rgb : out std_logic_vector(2 downto 0));
end RGB_Gen;
architecture first of RGB_Gen is
component counter IS
PORT ( clk : IN STD_LOGIC; -- clk should be 100 Mhz
rst : IN STD_LOGIC;
one_second : OUT STD_LOGIC);
END component;
type state_type is (off, Blue, Green, Cyan, Red, Magneta, Yellow, White);
signal state, next_state: state_type;
signal one_second : std_logic;
begin
count : counter
port map (clk => clk, rst=>rst, one_second => one_second);
state_assignment: process (clk) is
begin
if rising_edge(clk) then
if (rst = '1') then
state <= off;
else
state <= next_state;
end if;
end if;
end process state_assignment;
fsm_process: process (state, clk) is
begin
case state is
when off =>
if one_second='1' then next_state<=Blue;
else next_state <= state; end if;
when Blue =>
if one_second='1' then next_state<=Cyan;
else next_state <= state; end if;
when Cyan =>
if one_second='1' then next_state<=Green;
else next_state <= state; end if;
when Green =>
if one_second='1' then next_state<=White;
else next_state <= state; end if;
when White =>
if one_second='1' then next_state<=Yellow;
else next_state <= state; end if;
when Yellow =>
if one_second='1' then next_state<=Red;
else next_state <= state; end if;
when Red =>
if one_second='1' then next_state<=Magneta;
else next_state <= state; end if;
when Magneta =>
if one_second='1' then next_state<=off;
else next_state <= state; end if;
end case;
end process fsm_process;
rgb <= "000" when state = off else
"001" when state = Blue else
"011" when state = Cyan else
"010" when state = Green else
"111" when state = White else
"110" when state = Yellow else
"100" when state = Red else
"101" when state = Magneta else
"000";
end first;
-------Counter Entity-----------
library ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY counter IS
PORT ( clk : IN STD_LOGIC; -- clk should be 100 Mhz
rst : IN STD_LOGIC;
one_second : OUT STD_LOGIC);
END counter;
ARCHITECTURE second of counter is
signal counter : unsigned (26 downto 0); -- 134,217,728 * 1/100 Mhz =
1.34217728 second
BEGIN
count_one_sec : process (clk)
begin
if rising_edge(clk) then
if (rst = '1') then
counter <= (others => '0');
else
if (counter = 10) then
counter <= (others => '0');
else
counter <= (counter + 1);
end if;
end if;
end if;
end process count_one_sec;
one_second <= '1' when (counter=10) else '0';
end second;
--------------------------------------------------------------------------------------------