You will create an eight-digit seven-segment display controller using a sequential counter and dataflow SystemVerilog.
In the seven segment decoder laboratory assignment, you created a circuit that can display a hexadecimal value on a single digit. In this lab, we are going to create a seven-segment controller that can display a unique value on each digit of the eight-digit display. Displaying multiple digits on the display is accomplished by multiplexing the cathode signals and “driving” or displaying one digit at a time. To make it appear to the human eye that more than one digit is displayed, we need to rapidly turn on each digit and sequence through the digits fast enough so the eye and brain cannot see this sequencing. Even though only one digit is actively displayed at a time, our persistence of vision and slow brain response cannot perceive this single digit display strategy. Instead, it will appear as if all eight digits are being displayed at the same time. If you were to take a high-speed video of the display, you would see this sequential digit display approach in action.
The example shown below demonstrates how the value “0123” is displayed on the first four digits of the display using time multiplexing. In this example, only one digit is being driven on the display at a given time – digit “0” is displayed on digit 3 (the left most digit) during the first time period, digit “1” is displayed on digit 2 during the second time period, digit “2” is displayed on digit 1 during the third time period, and digit “3” is displayed on digit 0 (the right most digit) during the fourth time period. This process of displaying one digit at a time repeats continuously to make it appear that all four digits are being displayed at the same time.
This example demonstrates the signals that must be asserted during each time period to produce the desired display. During the first time period, AN3 is asserted (i.e. is low) and the other annode signals are deasserted. The following cathode signals are asserted (driven low) to display the character “0” on digit 3: CA, CB, CC, CD, CE, and CF. During the next digit period, AN2 is asserted (while AN2 is deasserted) and the following cathode signals are asserted to display the character “1”: CB and CC. Next, AN1 is asserted and the following cathode signals are asserted to display the character “2”: CA, CB, CC, CD, and CE. Finally, AN0 is asserted and the following cathode signals are asserted to display the character “3”: CA, CB, CC, CD, and CG. This process repeats continuously to keep all four values actively highlighted on the four-digit display.
The challenge we have is deciding how long to drive each anode signal. If the “on” time of the anode signals is too long, the eye and brain will detect that only one digit is being displayed at a time and we will see the digits turn on and then off in sequential order. If the “on” time is just right, human brain will perceive all four characters as being displayed at the same time through persistence of vision.
What do you think will happen to the display if the time to turn on each digit is too short?
The easiest way to sequence through the eight different digits is to create a “free running” counter. A free running counter is a counter that increments continuously at each clock cycle (See Figure 16.6). When the free running counter reaches all 1's, it will then roll over to zero on the next clock cycle. The top three bits of this free running counter will cycle through the digits, while the rest of the bits of the counter will determine the amount of time to display each digit. For example, if you used an 8-bit counter then the top three bits of the counter would determine which digit to display and the bottom 5 bits would be used to count the duration that each digit is displayed. With 5 bits, each digit will be displayed for 25 = 32 clock cycles.
The table below summarizes how the top three bits of this free running counter are used to select the appropriate digit in the display:
Top 3 Bits | Function |
---|---|
000 | Display digit 0 (right most) - Assert AN0 |
001 | Display digit 1 - Assert AN1 |
010 | Display digit 2 - Assert AN2 |
011 | Display digit 3 - Assert AN3 |
100 | Display digit 4 - Assert AN4 |
101 | Display digit 5 - Assert AN5 |
110 | Display digit 6 - Assert AN6 |
111 | Display digit 7 (left most) - Assert AN7 |
The clock we have on the NEXYS 4 board runs at 100 MHz with a clock period of 10 ns. If you use an eight-bit counter to sequence the digits as described above, the top three bits would be used to sequence through each digit and the bottom five bits would be used to count the number of clock cycles to display each digit. Thus, each digit would be displayed for 25 x 10 ns = 320 ns. For this laboratory, you will need to create a counter that displays each digit for at least 160 us.
Determine the minimum number of bits needed for a counter to display a single digit for at least 160us (160000ns). If we add 3 bits to sequence through all 8 digits, what is the total required?
Assume your counter counts from 0 to 2n-1 where n is the size of your counter. How long it will take to cycle through all eight digits?
The first exercise of this lab is to create a SystemVerilog module for your seven segment controller. The purpose of this controller is to provide an easy to use interface for others so that they can easily use the seven segment controller without having to figure out all of the details associated with properly sequencing through all of the digits. Your controller will have the following three important inputs:
Begin this exercise by creating a module with the following input and output ports:
Module Name: SevenSegmentControl | |||
---|---|---|---|
Port Name | Direction | Width | Function |
clk | Input | 1 | 100 MHz System Clock |
reset | Input | 1 | Active high reset, which resets the counter |
dataIn | Input | 32 | Data value to display |
digitDisplay | Input | 8 | Indicates which digits to display |
digitPoint | Input | 8 | Indicates which digit points to turn on |
anode | Output | 8 | Anode signal for each of the 8 digits |
segment | Output | 8 | Segment signals ([7] is digit point, [6:0] are regular segments) |
The seven segment controller is composed of the following three major sections:
Each of these logic sections will be described below.
After creating your module interface, create the counter that will sequence through the eight digits. Create your counter according to Figure 16.6 of the textbook. You will need n bits for your counter, where n is the number of bits you calculated in the preliminary. You may use behavioral SystemVerilog, as shown in Program 17.5.2.
After creating your counter, create a three-bit signal, digitSelect, that is used to select which digit is being displayed. You will use this signal in several places throughout the circuit. Remember that this is just the top three bits of your counter so you can use a simple assign statement to set digitSelect equal to those three bits.
As described in the preliminary you will turn on only one anode signal at a time. The anode signal of a digit should only be asserted to a '0' (remember that the anode signal is reversed) under the following two conditions:
In all other conditions the anode signal should be set to a '1' (thus turning off the digit).
We can accomplish this in three steps:
Drawing this out might help you visualize the process.
The logic for the cathode signals is fairly straightforward. We will use the digitSelect signal to decide which four bits of the dataIn to display, connect that to our seven segment decoder, and create logic for our digit point.
A four-bit 8:1 multiplexer will select four bits from the 32-bit data input (top left block in figure). The output of the multiplexer then connects to a seven segment decoder that converts the four-bit number into the appropriate cathode signals as you did in the Seven Segment Decoder lab. First create an 8:1 mux that uses digitSelect as your select line and dataIn as your input. Then, instead of instancing your old Seven Segment module, create the decoder using dataflow statements and place it in your existing module (you should already have this code from the Dataflow lab). This will make it simpler to reuse your Seven Segment Controller in later labs.
Finally, you will need an 8:1 multiplexer for the digit point cathode logic.
Exercise 1 Pass-off: Show a TA your completed module and briefly explain how your anode and cathode sections work.
In this exercise you will simulate your seven segment controller to verify that it functions as you expect it should. This controller is the most complex circuit you have created so far and you will likely have logic problems in your circuit. It is very important that you resolve any logic problems at this point before moving to the top-level design. You will simulate your controller in two ways: with a simple TCL script and a testbench.
TCL Script
In the first simulation step, perform a simple simulation by writing a TCL script and testing the primary functions of the controller. You will not need to exhaustively test all of the features of your controller but you should verify that the major functions of the controller are working properly.
The TCL script below provides a start for such a simulation. Re-read this tutorial if you want to review TCL commands .
restart # Set a repeating clock add_force clk {0 0} {1 5} -repeat_every 10 add_force reset 1 run 20ns add_force reset 0 # set default values for the inputs add_force -radix hex dataIn 01234567 add_force digitPoint 11111111 add_force digitDisplay 11111111
Extend this script by adding the following:
After running your simulation script, carefully analyze the waveform of the outputs to test the following features of your controller:
Resolve any obvious problems with your controller before proceeding to the testbench simulation.
Include a copy of your TCL simulation script
Testbench
After resolving any major issues with your seven-segment controller, you can more thoroughly test your controller with a testbench. This simulation testbench tests many different cases and may find problems with your controller that are not obvious. Download the following testbench, add it as a simulation source to your project, and simulate your controller. This simulation will take a relatively long time (about 2 minutes) and you will need to “run” the simulation until you get the “done” message from the console (about 30ms in total).
Resolve any problems identified by the testbench and simulate your controller until your controller passes all of the testbench cases.
Include a copy of your seven segment controller SystemVerilog
Exercise 2 Pass-off: Show a TA your extended tcl script and your testbench output.
The final design exercise is to create a top-level module that uses your seven segment display controller to display various settings and values on the buttons. Begin this exercise by creating a new SystemVerilog module with the following name and ports:
Module Name: SevenSegmentControlTop | |||
---|---|---|---|
Port Name | Direction | Width | Function |
clk | Input | 1 | 100 MHz System Clock |
CPU_RESETN | Input | 1 | Active-low reset button |
sw | Input | 16 | 16 Slide switches to determine what to display |
btnc | Input | 1 | Assert all segments (test mode) |
btnr | Input | 1 | Blank the display |
segment | Output | 8 | Cathode signals for seven segment display |
anode | Output | 8 | Anode signals for each of the eight digits |
Begin the body of your module by instancing your seven segment controller and attaching the clk
input to the top-level clock, the CPU_RESETN
to the reset
input (remember to invert it), and the segment
and anode
signals to the top-level segment
and anode
signals. You will need to create additional logic to control the other signals of your seven segment controller (dataIn, digitDisplay, and digitPoint). In particular, your logic will generate the values for these signals based on the values of the top-level buttons and switches. The figure below provides a high-level diagram of how you should organize your top-level design.
The statements below describe how the seven segment display should operate under a number of different conditions. You will need to create dataflow logic that uses the buttons and switches from the top-level design and drive the dataIn, digitDisplay, and digitPoint inputs to your seven segment display controller. Note that these statements below are listed from highest to lowest priority (for example, if both btnc and btnr are pressed at the same time, btnc's function has priority).
Note that in the default case you are connecting the switches only to the bottom four digits (both 16 bits wide). Since the top four digits are blank, it does not matter what you assign the top 16 bits of dataIn to.
After creating your top-level SystemVerilog file (and resolving any compilation errors), simulate your file to see that it operates as you expect it should. Create a .tcl simulation file that does the following:
Once you are satisfied that your module operates correctly, proceed to the next exercise.
Include a copy of your top-level .tcl simulation script
Include a copy of your top-level SystemVerilog file
Perform the steps of Synthesis, Implementation, and Bitstream Generation. Download your design and experiment with several cases to demonstrate that it is working properly.
Provide a summary of your synthesis warnings.
Summarize the size of your circuit (LUTs and FFs).
Pass off your laboratory by demonstrating the following to the TA:
How many hours did you work on the lab?
Please provide any suggestions for improving this lab in the future.
Here are some ideas for personal exploration in this laboratory:
Describe your personal exploration activities