Purpose
Through this lab, I sought to familiarize myself with the Cmod A7 FPGA board and the software environment, Xilinx's Vivado, that I would be using to program it. Using Vivado I will be able to synthesize and implement a design including both source and constraint files that will allow me to drive a four-digit seven-segment display on a breadboard.
7-Segment Background Info
As the Cmod A7 does not have a built in four-digit seven-segment display, my first task was figuring out how to properly connect the output pins I specified within the constraint file to match up to the display's pinout. I began by researching the documentation behind the displays I was using.
Together, the images make it very simple to understand what is going on behind the scenes when driving a 7-segment display. The seven segments of each display are referred to as A, B, C, D, E, F, and G. To create numbers on the displays, you would only need to illuminate the segments needed to represent that number. For example, to create a '1', segments B and C must be high. For an '8', all of the segments will be powered. Lastly, there is one anode pin to send power to each LED segment. Whichever segment is grounded will then illuminate appropriately.
Let's now consider the case of a 4-digit 7-segment display.
This may look a more complex, but don't worry. It's still relatively simple to understand. There 4-digit 7-segment display is simply four 7-segment displays, like we just discussed, tied together. They all share the same segment pins of A through G, they just have separate anodes. For now we will just look into displaying the same value on each display. We will discuss multiplexing and displaying separate values in part 2.
VHDL Program
Now that you understand how to manage the hardware with a 7-segment display, we can look to writing the software that drives the displays. This code can be found on my GitHub repository here.
The first program we will look at is the "leddec.vhd" file.
Seg is a 7 bit signal, where the left-most digit represents 'A' and the right-most represents G.
Data is a 4 bit signal that contains the binary representation of the hexadecimal value we are going to display. For example, '0001' is '1' in hexadecimal.
Each line of the WHEN ELSE statement translates the number represented by data into the appropriate segment values.
When data is '0000', all segment LEDs are illuminated except for G, which is the center one, two represent a '0' on the display.
Lastly, the anode signal is 4 bit, where each bit indicates if a display should be powered on or off. Here, '1' indicates the display will be powered.
Since this is the first lab, I will also quickly explain how a constraint file works.
Each of the signals used in the code example above is mapped in the constraint file to a general purpose input/output pin (GPIO) on the FPGA board.
Here, the 4 bits of data is mapped to pins 1 through 4. The 7 bits of seg are mapped to pins 7 to 13. Lastly, the 4 bits of anode are pins 14 and 17-19.
Putting It All Together
We understand how the 4-digit 7-segment displays are controlled, and we have software to accompany that. Now we need to connect the pins between the FPGA board and the actual display. The video embedded below is a full walk through of how to connect the wiring and inputs to match the definitions in the constraint file.
The red and black wires connect the 3.3 Volt output of the Cmod A7 board to all of the power rails within the breadboard. The seven white wires connect the pins from the board to their respective segment, ranging from A to G. The four blue wires are the anodes for each of the displays. Lastly, the green wires connect the four momentary pushbuttons to the Cmod A7 board as inputs. These four buttons represent the data signal. As demonstrated at the end of the video, this counter can utilize the momentary pushbuttons to range from values of 0 to F, as well as turn on the respective display driven by the Cmod's two internal push buttons.
Now that we've created a hexadecimal counter that is driven off of user input in the form of momentary push buttons, we can look to utilize another amazing feature of FPGAs; the clock.
At the heart of modern computing systems lies the clock. The clock essentially pulses a voltage output at extremely consistent, and fast, rates. The clock internal to the Cmod A7 board has a rate of 12MHz, meaning the clock pulses 12 million times each second. That's quick.
The clock on a given FPGA can be accessed using the constraint file, demonstrated in the image below.
Here, we have defined a port called "sysclk" which will be the 12 MHz clock built into the Cmod board.
We can utilize this clock to drive the updating of our counter, rather than using the push button inputs from before. The clock we're using is extremely quick for this application -- too quick in fact. To counteract this, we have it count bit by bit for a 29 bit signal, and only update the counter with the 4 most significant bits. Otherwise, the display would be flickering too fast for us to understand what is going on. These 4 bits become our data.
The counter program to the left increments the value of 'cnt', a 29 bit signal whenever the clock moves from low to high in emitting a pulse.
The top 4 bits of 'cnt' are mapped to 'count' on line 21, which will be utilized in our top most file called 'hexcount.vhd'. Hexcount will pass the values in 'count' along to data from before.
Under Lab 1 on my CPE 487 repository on my GitHub, you will find the hexcount.vhd program I just mentioned. That is our 'master' file, as it dedicates the other two as components allowing the user to interact on a higher level with all of the ports in each file. This combination of files allow us to send the counter from one file to the segment decoder in another file.
Lastly, we just need to run the code! Here's a video of the program successfully running on my Cmod.