Lab 1: Five-Bit Numeric Display
Part B: Optimized Code
Lab 1 is a warmup designed to give you experience designing, implementing, testing, and prototyping a simple Verilog hardware design. This lab will focus primarily leverage on concepts from Topic 2: Combinational Logic and Topic 3: Boolean Algebra.
You will be implementing a five-bit numeric display that takes as input a five-bit binary value and displays this value as a decimal number using two seven-segment displays. Your implementation will exclusively use combinational logic gates. This five-bit numeric display will be reused extensively across all of the remaining labs. The lab includes four parts:
-
Part A: Unoptimized Code and Testing
- Must be completed individually
- Due 9/11 @ 11:59pm via GitHub
- Students should work on Part A before, during, and after your assigned lab section during the week of 9/8
-
Part B: Optimized Code and Testing
- Must be completed individually
- Due 9/18 @ 11:59pm via GitHub
- Plan to start on Part B during the week of 9/8
- Even though Part B is due on 9/18 you still need the code ready to go before your lab section the week of 9/15!
-
Part C: FPGA Analysis and Prototyping
- Done with randomly assigned partner
- Due week of 9/15 during assigned lab section
- Even though completed with a partner, every student must turn in their own paper check-off sheet in their lab section!
-
Part D: Report
- Done with same partner as in Part C
- Due week of 9/15, three days after lab section @ 11:59pm via Canvas
This handout assumes that you have read and understand the course tutorials and that you have attended the discussion sections. You should have already cloned your individual remote repository, so use git pull to ensure you have any recent updates before working on your lab assignment.
Students will must try to get Part B working before their lab section the week of 9/15. You might have a little time at the beginning of your lab section the week of 9/15 to fix a bug, but if your code is not almost finished you might not have enough time to finish Part C during your assigned lab section!
Your repo includes the following files in the lab1
subdirectory for
Part B. These files are for modeling real hardware using the
synthesizable subset of Verilog.
BinaryToSevenSegOpt_GL.v
: Binary-to-seven-segment converter (optimized)DisplayOpt_GL.v
: Five-bit numeric display (optimized)
Your repo includes the following files in the lab1/test
subdirectory.
These files are for systematic and automatic testing of your hardware
using the non-synthesizable subset of Verilog.
BinaryToSevenSegOpt_GL-test.v
: Test bench for binary-to-seven-segment (optimized)DisplayOpt_GL-test.v
: Test bench for five-bit numeric display (optimized)
Part B is divided into two steps. Complete each step before moving on to the next step.
- Step 1. Implement and test
BinaryToSevenSegOpt_GL
- Step 2. Implement and test
DisplayOpt_GL
1. Unoptimized vs Optimized Implementations
Your design for the binary-to-seven-segment converter in Part A was not
terribly optimized; we should be able to implement the same truth table
with fewer combinational logic gates. In this part, you should use what
you have learned in lecture on Boolean algebra (especially Karnaugh maps)
to see if you can reduce the amount of logic required to implement the
binary-to-seven-segment converter. You should use
BinaryToSevenSegOpt_GL
for your optimized implementation.
We strongly recommend taking a incremental design approach! Start by
copying your unoptimized implementation into BinaryToSevenSegOpt_GL
.
Then pick a single output port to optimize. Work through the
corresponding Karnaugh map and replace just the logic for that output
port with the newly optimized version. Leave all of the logic for the
other output ports unoptimized. Then use your tests to verify the
converter is still working. If not, you know where to focus your
debugging. If so, you can move on to the next output port.
Once you have implemented (and thoroughly tested!) your optimized
binary-to-seven-segment converter, you can then instantiate this
optimized unit within DisplayOpt_GL
to create an optimized five-digit
numeric display. Note that students do not need to optimize their
binary-to-BCD converter.
2. Testing Strategy
You will use a similar strategy as in Part A to ensure all of your implementations are correct.
2.1. Linting
You can use the same linting strategy you used in Part A.
% cd ${HOME}/ece2300/netid
% verilator --Wall --lint-only lab1/BinaryToSevenSegOpt_GL.v
% verilator --Wall --lint-only lab1/DisplayOpt_GL.v
2.2. Systematic Unit Testing
There is no need to write any new test cases for Part B. You will just be reusing the test cases you wrote for Part A. To see how this works look in these test benches:
BinaryToSevenSegOpt_GL-test.v
DisplayOpt_GL-test.v
You can run your tests just like in Part A.
% cd ${HOME}/ece2300/netid
% iverilog -Wall -g2012 -o BinaryToSevenSegOpt_GL-test lab1/test/BinaryToSevenSegOpt_GL-test.v
% ./BinaryToSevenSegOpt_GL-test
% iverilog -Wall -g2012 -o DisplayOpt_GL-test lab1/test/DisplayOpt_GL-test.v
% ./DisplayOpt_GL-test
3. Automated Build System
Constantly entering commands on the command line to lint, compile, and run tests can quickly become tedious. In the third discussion section, students will learn about a build system we can use to automate this process. We will be pushing this build system into student's repos on Friday 9/12 so that students can use the build system to work on Part B and get ready for Part C.
The automated build system involves the following new files in your repo:
Makefile.in
: Makefile for the build systemconfigure
: Configure script for the build systemconfigure.ac
: Used to generate the configure scriptscripts
: Scripts used by the build system
It will also add a lab1.mk
file to the lab1
subdirectory which is
used to tell the build system about all of the files in Lab 1.
When using the automated build system we always work in a build
directory. This simplifies keeping the generated files separate from the
source files. You should be able to trash the build directory at any time
for a "clean build". This is particularly useful if something seems to be
going seriously wrong; a "clean build" is sometimes all you need to fix
the issue.
3.1. Configuring the Automated Build System
Here is how to create the build directory and configure the automated build system.
3.2. Building Tests
Here is how to build and run the tests for the unoptimized binary-to-seven-segment converter.
% cd ${HOME}/ece2300/netid/build
% make BinaryToSevenSegUnopt_GL-test
% ./BinaryToSevenSegUnopt_GL-test
% ./BinaryToSevenSegUnopt_GL-test +test-case=1
% ./BinaryToSevenSegUnopt_GL-test +test-case=2
% ./BinaryToSevenSegUnopt_GL-test +test-case=2 +dump-vcd=waves.vcd
The build system takes care of using Verilator to lint your design, using our own custom linter to check rules specific to ECE 2300, and using Icarus Verilog to compile your design into a simulator. Here is how to build and run the remaining tests.
% cd ${HOME}/ece2300/netid/build
% make BinaryToBinCodedDec_GL-test
% make BinaryToSevenSegOpt_GL-test
% make DisplayUnopt_GL-test
% make DisplayOpt_GL-test
% ./BinaryToBinCodedDec_GL-test
% ./BinaryToSevenSegOpt_GL-test
% ./DisplayUnopt_GL-test
% ./DisplayOpt_GL-test
It can be convenient to build and run a test using a single command line like this so you can just use the up-arrow key to quickly rebuild and rerun a test.
% cd ${HOME}/ece2300/netid/build
% make BinaryToSevenSegUnopt_GL-test && ./BinaryToSevenSegUnopt_GL-test
You can build and run all of the test with the check
target like this:
3.3. Building Interactive Simulators
You can build and run the interactive simulator like this:
4. Lab Code Submission
To submit your code you simply push your code to GitHub. You can push
your code as many times as you like before the deadline. Be sure to
verify your code is passing your tests both on ecelinux
and on GitHub
Actions. Your design code will be assessed both in terms of code quality,
verification quality, and functionality.
4.1. Part A Revisions
If your design is failing some tests from Part A, we encourage you go ahead and fix whatever is wrong. If your design is passing your tests but failing our tests consider using the staff tests for inspiration on how to improve your own testing. Fixing whatever is wrong now can improve your code functionality score and also ensures that you can use your work from this lab in future labs.
To revise your Part A submission, simply push improvements on the regular main branch. After improving your code, you must enter a comment in the Part A grading pull request that explains what was wrong and how you fixed it. The only way we can increase your score after a revision is if you clearly explain what was wrong and how you fixed it. If you fix your code on the main branch and do not explain it in the pull request then you will not receive a revised score!
All revisions need to be finalized by the due date for Part B. No revisions are allowed for Part B code.
4.2. Code and Verification Quality
Code and verification quality will be assessed in the same way as for Part A.
4.3. Functionality
Your functionality score will be determined by running your code against a series of tests developed by the instructors to test its correctness. Note that we will be using the automated build system to test your final code submission as shown below.