Table of Contents
Sequence 1: The Original
Design
Sequence 2: Simple
Alternating Sequence
Sequence 5: Double
Zig-Zag Sequence
Sequence 7: Reverse Spin
Sequence
Frequency Divider VHDL
Listing
Sequence 1: Original
Design Sequence
Sequence 2: Simple
Alternating Sequence
Sequence 5: Double Zig
Zag Sequence
Sequence 7: Reverse Spin
Sequence
Top-Level Component VHDL
Listing
This Christmas Light decoration is a project I conceived many years ago with the idea of having each of the letters that make up the words Merry Christmas light up on its own. The idea originated back when I was in middle school and was based on a simpler project I was working on at the time. This project was built with a small cardboard box, a light that was capable of blinking on and off, and a DC power source. To describe it as simply as possible, this project was built up by drawing the letters of Merry Christmas on one side of the box, then taking a piece of a red plastic bag and lining it across the inside of the side with the letters cut out. Aluminum foil was used to line the remaining sides to reflect the light from the light bulb to make the letters brighter. The light bulb was then wired to a DC power source and placed inside the box. The bulb itself was one of those flashing bulbs that came from a string of lights that go to a Christmas tree, therefore I manage to get the effects of a flashing light using the most basic DC source to light bulb circuit with a switch in between.
Figure 1:
Christmas Light Decoration Middle School Diagram
The red arrows indicate desired light direction.
The brown box had the letters Merry Christmas cut into the side lined with red
plastic.
This simple project was a marvel to those who observed it functioning at the time and gave me some ideas on how I could make it even more dazzling. I had envisioned separating the letters and lighting them up individually, perhaps in a pattern or some sort. However, at the time, my knowledge of electronics was limited on experiments I did at home and what I learned in my 4th grade science class. I did not know much about the various electronic components and their functions therefore, the idea was put aside for the time being.
Fast forward to my college years and after taking a digital electronics undergrad course I decided to design the Christmas light project that I had envisioned back in middle school. I knew from taking the course that I could achieve the pattern using a binary counter and decoder logic. After considering various circuits for generating the lights beginning with using small incandescent lights, I finally settled on using high brightness LEDs due to their much longer life expectancy and their smaller power requirements. At first I was going to simply implement red LEDs that turn on and off but later decided to include green LEDs that turn on when the red LEDs were off. After some consideration on how I could achieve this I concluded that this could be achieved by simply treating them as logic probes that operate like the off the shelf logic probe devices purchased at electronics stores. The original design consisted of a timer, a binary counter, and a set of gates that provided the decoder logic for one sequence. Given the more powerful capabilities of the Xilinx FPGA device and the use of VHDL to program it, I took this design a step further and added multiple sequences and multiple frequencies for the set of lights. The final design will be covered in greater detail in the following sections.
The Christmas Light decoration project consists of 14 LEDs wired as logic probes with each probes lighting each of the letters in the words “Merry Christmas.” The heart of the design consists of a binary counter that continuously counts upwards from 0 to 15 with each rising edge of the clock signal. The outputs of the counter are then fed into the inputs of a decoder module that decodes the signals into one of eight selected patterns.
Figure 2: Christmas Light Decoration Block Diagram
This design was enhanced from the original design which consisted of a single 1 Hz frequency clock and a single sequence to provide a range of various frequencies and eight selectable sequences. The frequency is selected by 5 input switches for the FRQ input and 3 input switches for the SEQ input. From the block diagram, the design consists of a frequency generator, frequency divider, binary counter, and four-bit decoder that turns on and off the lights based on the output of the binary counter.
The frequency generator for this design comes from the 100 MHz oscillator clock provided by the Basys 3 trainer board used to develop and test this design. This clock is connected to pin W5 which is an MRCC input on bank 34 of the Artix-7 FPGA device.[1] The Clocking Wizard IP provided by the Xilinx Vivado tools is used by this design to generate a 16 MHz clock frequency used to drive the frequency divider component of this design.
Figure 3: Xilinx Vivado Clocking Wizard IP
This Clock Wizard IP was customized to provide a 16 MHz output on the signal PCLK (primary clock) with the 100 MHz signal driving the MCLK (master clock) input. This wizard was also customized to provide an active low reset input (resetn) that will be driven by the master reset input from the top-level design.
The primary clock output signal (PCLK) of the Clocking Wizard IP drives the clock input (CLK_IN) of the frequency divider stage. This stage takes the selected frequency provided by the five input switches (CLK_SEL) and divides the input frequency to provide a frequency output from 1 Hz to 16 Hz. The stage is designed to work optimally when only one of the 5 inputs are active and the output clock frequency is undefined if multiple inputs are active. I envisioned using a five-way rotary or sliding switch that activates only one of these inputs at a time for a final prototype. However, for the demonstration on the Basys 3 trainer board, five of the 16 available switches provided will be used.
This component consists of two processes written in
VHDL. The first process is a MHz to Hz
frequency divider that takes the 16 MHz signal and divides it to a 16 Hz signal
that is used by the second process. To
simplify this component, I attempted to make the output frequency of the
Clocking Wizard IP signal (used in the frequency generator stage) to be
16,777,216 Hz. Since this is 16 times
the value of 220, I could simply use the value of the 20th
bit of a 20-bit counter to generate the output signal of 16 Hz. The actual frequency output (as indicated by the
Clocking Wizard IP) of 16.777 MHz is “good enough for government use.”
-- The MHz to Hz stage of the frequency divider. MHz2Hz: process(CLK_IN) variable
mhertz_count : std_logic_vector(19 downto 0); begin -- Increment the count on the rising edge of the clock. if CLK_IN'event and CLK_IN = '1' then mhertz_count := mhertz_count + 1; end if; -- Set the clock in Hz signal to MSB of count. CLK_HZ <= mhertz_count(19); end process; |
VHDL
Listing for the MHz to Hz frequency divider process. |
The second process of the frequency divider component divides the 16 Hz output
signal of the previous process to a selectable set of output frequencies of 1,
2, 4, 8, or 16 Hz. This process works
optimally when only one of the selection inputs are active.
-- The frequency divider output stage. FRQDIV: process(CLK_HZ, CLK_SEL) variable count : std_logic_vector(4 downto 0); variable outp : std_logic_vector(4 downto 0); begin -- Increment count on rising edge of CLK_HZ. if CLK_HZ'event and CLK_HZ = '1' then count := count + 1; -- Setup the output clock port. for i in 4 downto 0 loop outp(i) := (CLK_SEL(i) and count(i)); end loop; end if; -- Set the output clock signal. CLK_OUT <= outp(4) or outp(3) or outp(2) or outp(1) or outp(0); end process; |
VHDL Listing for the selectable frequency divider output process. |
The complete listing of the VHDL source code for this component of the design is provided in the appendix section of this report. This component did not simulate properly using either the Xilinx Vivado or the Active HDL software but the final VHDL was synthesized and tested in the Basys 3 device.
Figure 4: Frequency Generator and Divider Testing (video)
The switches on the far-left control the frequency and the fifth switch from the right is the master reset. The LED on the far-right is the oscillating output of the frequency divider.
The binary counter is modelled after the 74161 synchronous presettable binary counter in VHDL. In this design, it is configured to count upwards continuously from 0 to 15 with none of the other functionality of the component being utilized. The output signals are connected to the decoder stage to decode the current count into one of the eight selectable light sequences. The functions of this device were derived in VHDL to mimic the following features and provide the following interface.[2]
Pin |
Symbol |
Description |
1 |
MR |
asynchronous master
reset (active low) |
2 |
CP |
clock input
(low-to-high, edge-triggered) |
3 |
P0 |
Parallel data input |
4 |
P1 |
Parallel data input |
5 |
P2 |
Parallel data input |
6 |
P3 |
Parallel data input |
7 |
CEP |
count enable input |
8 |
GND |
ground |
9 |
PE |
parallel load enable
input (active low) |
10 |
CET |
count enable carry
output |
11 |
Q3 |
counter output |
12 |
Q2 |
counter output |
13 |
Q1 |
counter output |
14 |
Q0 |
counter output |
15 |
TC |
terminal count output |
16 |
Vcc |
supply voltage |
74161 Presettable Binary Counter with Asynchronous Reset
Function Table |
||||
SR |
PE |
CET |
CEP |
Action on the rising clock edge. |
0 |
X |
X |
X |
Reset (clear) Q goes to zero. |
1 |
0 |
X |
X |
Load (Pn --> Qn) |
1 |
1 |
1 |
1 |
Count (Increment) |
1 |
1 |
0 |
X |
No Change (Hold) |
1 |
1 |
X |
0 |
No Change (Hold) |
Source: Motorola Fast and LS TTL
Data |
This stage was implemented and tested like the lab exercise in module 4 that implemented and tested the MC14510B Up/Down BCD Counter in VHDL. Unlike that counter, the 74161 binary counter does not have bidirectional counting capability but it does utilize a terminal count (TC) output that functions similarly to the carry output of the MC14510B device. Like the BCD device, this device can also be configured in stages to allow for larger count values with 4-bits per stage. This feature, however, was not tested since it was not required for the larger design but the component itself was tested and simulated thoroughly.
Figure 5: Simulation Results of the 74161 Binary Counter
The VHDL was also synthesized and tested using the Basys 3 device to ensure that there were no subtle differences between the simulation and how the component functions in actual hardware.
Figure 6: Testing Results of the Binary Counter (video)
The LEDs on the far right are the Q outputs of the binary counter and the switches just below them are the P inputs (set to 1010). During testing, the CET, CEP, and PE switches were tested to see their effects on the component. The LED on the far left is the TC terminal count output. The complete VHDL listing of the 74161 binary counter component is provided in the appendix.
The decoder stage takes the outputs of the counter stage and decodes them according to the selected sequence. For each count of the binary counter (0 to 15) the decoder outputs a high or low voltage (1 or 0) for each of the letters of the words Merry Christmas per the truth table of the selected sequence. The design calls for 8 selectable sequences selected by the operator. The truth tables for each of the sequences show the patterns for the lights based on the outputs (A, B, C, and D signals) of the binary counter with a one for the letter indicating that the light will be red and a blank indicating the light will be green.
The decoding logic for each of the designs was accomplished by using Karnaugh Maps to determine the logic that drives each of the letters in the sequences. For brevity, the K-Maps will be provided in the appendix section along with the complete listing for this component. For each of the sequences the final decoder logic derived from each set of K-maps will be provided with the truth tables in the following subsections.
This was the pattern I put together for an earlier design of this project that used TTL logic gates to decode the output of an actual 74161 binary counter. This pattern had to reduce well to limit the chip count for the final decoder circuit. Reducing the chip count for a circuit design ensures that the final design consume less power during operation and costs less to produce. Utilizing the 7400 series of components instead of programmable logic device enables me to build the design without requiring the use of expensive programmers.
A |
B |
C |
D |
M |
E |
R |
R |
Y |
C |
H |
R |
I |
S |
T |
M |
A |
S |
0 |
0 |
0 |
0 |
1 |
1 |
||||||||||||
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||
0 |
1 |
0 |
0 |
1 |
1 |
||||||||||||
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||
0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||
1 |
0 |
0 |
0 |
1 |
1 |
||||||||||||
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||
1 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||
1 |
1 |
0 |
0 |
1 |
1 |
||||||||||||
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
Truth Table for the Original Design Sequence
This sequence has a lot of symmetry and a lot of letters turning on at the same intervals within the sequence. Therefore, the final decoding reduces as follows:
M1, Y, C, H, A, S2 = C AND NOT(D);
E, R2, R3, I, T, M2 = D OR (NOT(A) AND B AND C) OR (A AND NOT(B) AND C);
R1, S1 = B OR NOT(D);
This sequence just simply alternates between on and off for each letter as shown in the truth table.
A |
B |
C |
D |
M |
E |
R |
R |
Y |
C |
H |
R |
I |
S |
T |
M |
A |
S |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||
0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||
1 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||
1 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
Truth Table for the Simple Alternating Sequence
Due to the simplicity of this sequence, one only needs to look at the D output of the truth table to determine when the letters turn on or off for each interval. Letters M1, R1, Y, C, R2, S1, M2, and S2 are on when the D output is off and letters E, R2, H, I, T, and A are on when the D output is on.
M1, R1, Y, C, R3, S1, M2, S2 = NOT(D);
E, R2, H, I, T, A = D;
This sequence contains very little repeating patterns for the individual letters and no two letters followed the same pattern. Therefore, it was one of the most complicated to decode.
A |
B |
C |
D |
M |
E |
R |
R |
Y |
C |
H |
R |
I |
S |
T |
M |
A |
S |
0 |
0 |
0 |
0 |
1 |
1 |
||||||||||||
0 |
0 |
0 |
1 |
1 |
1 |
||||||||||||
0 |
0 |
1 |
0 |
1 |
1 |
||||||||||||
0 |
0 |
1 |
1 |
1 |
1 |
||||||||||||
0 |
1 |
0 |
0 |
1 |
1 |
||||||||||||
0 |
1 |
0 |
1 |
1 |
1 |
||||||||||||
0 |
1 |
1 |
0 |
1 |
1 |
||||||||||||
0 |
1 |
1 |
1 |
1 |
1 |
||||||||||||
1 |
0 |
0 |
0 |
1 |
1 |
||||||||||||
1 |
0 |
0 |
1 |
1 |
1 |
||||||||||||
1 |
0 |
1 |
0 |
1 |
1 |
||||||||||||
1 |
0 |
1 |
1 |
1 |
1 |
||||||||||||
1 |
1 |
0 |
0 |
1 |
1 |
||||||||||||
1 |
1 |
0 |
1 |
1 |
1 |
||||||||||||
1 |
1 |
1 |
0 |
1 |
1 |
||||||||||||
1 |
1 |
1 |
1 |
1 |
1 |
Truth Table for the Zig Zag Sequence
Due to no two letters having the same sequence, each of the letters had to be decoded individually.
M1 = NOT(B) AND NOT(C) AND NOT(D);
E = (NOT(B) AND NOT(C) AND D) OR (B AND C AND D);
R1 = C AND NOT(D);
R2 = (B AND NOT(C) AND D) OR (NOT(B) AND C AND D);
Y = B AND NOT(C) AND NOT(D);
C = NOT(A) AND NOT(B) AND NOT(C) AND NOT(D);
H = (NOT(A) AND NOT(B) AND NOT(C) AND D) OR (A AND B AND C AND D);
R3 = (NOT(A) AND NOT(B) AND C AND NOT(D)) OR (A AND B AND C AND NOT(D));
I = (NOT(A) AND NOT(B) AND C AND D) OR (A AND B AND NOT(C) AND D);
S1 = B AND NOT(C) AND NOT(D);
T = (NOT(A) AND B AND NOT(C) AND D) OR (A AND NOT(B) AND C AND D);
M2 = (NOT(A) AND B AND C AND NOT(D)) OR (A AND NOT(B) AND C AND NOT(D));
A = (NOT(A) AND B AND C AND D) OR (A AND NOT(B) AND NOT(C) AND D);
S2 = A AND NOT(B) AND NOT(C) AND NOT(D);
The diamond sequence expands and contracts the on states for the letters within the truth table to form a diamond pattern.
A |
B |
C |
D |
M |
E |
R |
R |
Y |
C |
H |
R |
I |
S |
T |
M |
A |
S |
0 |
0 |
0 |
0 |
1 |
1 |
||||||||||||
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
||||||||||
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
||||||||||
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||||
0 |
1 |
0 |
0 |
1 |
1 |
1 |
|||||||||||
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
||||||||||
0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
||||||||||
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||||
1 |
0 |
0 |
0 |
1 |
1 |
||||||||||||
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
||||||||||
1 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
||||||||||
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||||
1 |
1 |
0 |
0 |
1 |
1 |
1 |
|||||||||||
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
||||||||||
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
||||||||||
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
Truth Table for the Diamond Sequence
The K-Maps decoded this table as follows:
M1, Y, R3, M2 = C AND NOT(D);
E, R2 = D;
R1 = NOT(C) AND NOT(D);
C, S2 = B AND NOT(C) AND NOT(D);
H, A = (B AND NOT(C) AND D) OR (NOT(B) AND C AND D);
I, T = (NOT(B) AND NOT(C) AND D) OR (B AND C AND D);
S1 = NOT(B) AND NOT(C) AND NOT(D);
The double zig zag sequence takes two sets of lights and “zig zags” them side to side like the previous zig zag sequence pattern. Also, like the zig zag sequence in that there was little symmetry and no letters in the table that repeated the same pattern.
A |
B |
C |
D |
M |
E |
R |
R |
Y |
C |
H |
R |
I |
S |
T |
M |
A |
S |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
||||||||||
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
||||||||||
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
||||||||||
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||||
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
||||||||||
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
||||||||||
0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
||||||||||
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
||||||||||
1 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
||||||||||
1 |
0 |
0 |
1 |
1 |
1 |