Day 1 Lab: Welcome to Hardware Thinking¶
Starter Code
Download All Starter Code (.zip)
Individual exercise downloads and file links are below each exercise.
Week 1, Session 1 · Accelerated HDL for Digital System Design · UCF ECE
Overview¶
| Duration | ~2 hours |
| Prerequisites | Pre-class video (40 min): HDL vs. software, synthesis vs. simulation, module anatomy, digital logic refresher |
| Deliverable | Buttons-to-LEDs with at least one logic modification, programmed on Go Board |
| Tools | Yosys, nextpnr-ice40, icepack, iceprog, Icarus Verilog, GTKWave |
Learning Objectives¶
| SLO | Description |
|---|---|
| 1.1 | Explain why assign statements execute concurrently, not sequentially |
| 1.3 | Write a syntactically correct Verilog module with ANSI-style ports |
| 1.4 | Execute the full iCE40 toolchain: Yosys → nextpnr → icepack → iceprog |
| 1.5 | Use a .pcf file to map HDL signals to physical Go Board pins |
| 1.6 | Predict and verify the behavior of active-high LEDs and buttons |
Before You Start: Your Working Environment¶
Every exercise assumes you are working from inside the course repo with the Nix dev shell active. If this is your first time, complete the Toolchain Setup Guide first.
At the start of every lab session, do these four things:
# 1. Open a terminal (on Windows: open the Ubuntu/WSL2 terminal).
# 2. cd into your local clone of the course repo.
cd ~/hdl-for-dsd # adjust if you cloned elsewhere
# 3. Activate the course toolchain (skip if you set up direnv).
nix develop
# You should see the "HDL for Digital System Design — Environment" banner.
# 4. cd into today's lab directory. Every `make exN` command in this
# lab is run from here.
cd labs/week1_day01
Plug in the Go Board now, before running any make exN prog targets.
Exercises¶
Setup Verification (15 min)¶
With the Nix shell active and the Go Board connected, confirm every
tool reports a version. Run each command from labs/week1_day01/:
yosys --version
nextpnr-ice40 --version
icepack -h # icepack/iceprog have no --version; -h prints usage
iceprog -h
iverilog -V
gtkwave --version
If anything reports command not found, you are almost certainly
outside the Nix shell — re-run nix develop from the repo root.
Don't proceed with a broken toolchain.
How to check your work¶
Each exercise ships a self-checking testbench and a plaintext reference
solution under solution/. The starter Makefile adds one target:
make test— compiles your DUT against the published testbench and reports PASS/FAIL by comparing your output to the reference. Run it from the exercise'sstarter/directory. No keys, flags, or unlocking.
If you get stuck, the worked answer is in each exercise's ../solution/ref/.
Full background: scripts/lab_ctf/README.md.
Simulate before you program (optional but recommended)¶
Every Day 1 exercise ships a plaintext testbench under
exN_*/solution/tb/. From labs/week1_day01/:
make exN_sim # compile your starter DUT against the published tb, run vvp
make exN_wave # same, then open the resulting VCD in GTKWave
If you drop your own tb_<top_module>.v into the exercise's starter/
directory, that one wins; otherwise the published testbench is used
automatically. This is the same testbench make test runs — using it via make sim lets you inspect waveforms as you
debug.
Exercise 1: LED On — The Simplest Possible Design (20 min)¶
Exercise 1 — Code
Goal: Write, synthesize, and program the absolute minimum Verilog design. Confirm the full toolchain works end-to-end.
- Open
ex1_led_on/starter/ex1_led_on.v— the module is complete, just review it - From
labs/week1_day01/, build and program:make ex1 - Verify on hardware: LED1 on the Go Board should be lit
- Self-check:
cd ex1_led_on/starter && make test— passes when your output matches the reference - (Optional) Reference: the worked answer is in
../solution/ref/. - Reflection: What did Yosys actually synthesize here? Run
make ex1_stat(fromlabs/week1_day01/) to check LUT usage
Exercise 2: Buttons to LEDs — Wires in Hardware (25 min)¶
Exercise 2 — Code
Goal: Use assign to create combinational connections between inputs and outputs.
- Open
ex2_buttons_to_leds/starter/ex2_buttons_to_leds.v— direct mapping provided - Simulate first:
make ex2_sim(ormake ex2_wavefor GTKWave) — sweeps all 16 input combos against your DUT - From
labs/week1_day01/, build and program:make ex2 - Verify on hardware: Each button controls its corresponding LED
- Self-check:
cd ex2_buttons_to_leds/starter && make test— passes when your output matches the reference - (Optional) Reference: the worked answer is in
../solution/ref/. - Quick check: Are any LUTs used? Why or why not?
Exercise 3: Logic Between Buttons and LEDs (30 min)¶
Exercise 3 — Code
Starter .zip Solution .zip Makefile ex3_button_logic.v tb_button_logic.v
Goal: Implement concurrent combinational logic with multiple independent assign statements.
- Open
ex3_button_logic/starter/ex3_button_logic.v— fill in theTODOassignments - Predict the truth tables on paper first, then verify on hardware
- From
labs/week1_day01/, build and program:make ex3 - Self-check:
cd ex3_button_logic/starter && make test— passes when your output matches the reference - (Optional) Reference: the worked answer is in
../solution/ref/. - Discussion: All four
assignstatements are active simultaneously
| sw1 | sw2 | LED1 (AND) | LED3 (XOR) | LED4 (NOT) |
|---|---|---|---|---|
| released | released | ? | ? | ? |
| released | pressed | ? | ? | ? |
| pressed | released | ? | ? | ? |
| pressed | pressed | ? | ? | ? |
Exercise 4: Active-Low Thinking (20 min)¶
Exercise 4 — Code
Goal: Develop a clean boundary pattern for readable designs.
- Open
ex4_active_low_clean/starter/ex4_active_low_clean.v— fill in theTODOsections - The pattern: name inputs clearly at the boundary, keep internal logic readable, drive outputs directly
- From
labs/week1_day01/, build and program:make ex4 - Self-check:
cd ex4_active_low_clean/starter && make test— passes when your output matches the reference - (Optional) Reference: the worked answer is in
../solution/ref/. - Compare: Does this produce more or fewer LUTs than Exercise 3? Run
make ex4_stat
Exercise 5 — Stretch: Makefile & XOR Pattern (10 min)¶
Exercise 5 — Code
Goal: Automate the build flow and experiment with more gate combinations.
- Open
ex5_xor_pattern/starter/ex5_xor_pattern.v— add creative logic combinations - The day-level
Makefileinlabs/week1_day01/dispatches to each exercise's ownMakefile; open both and skim howmake ex5becomesmake -C ex5_xor_pattern/starter prog - From
labs/week1_day01/, build and program:make ex5 - Self-check:
cd ex5_xor_pattern/starter && make test— passes when your output matches the reference - (Optional) Reference: the worked answer is in
../solution/ref/. - Challenge: Can you make all 4 LEDs display a unique pattern based on the 4 buttons?
Deliverable Checklist¶
- [ ] Toolchain verified — all tools report version
- [ ] Exercise 1: LED1 lit on board,
make testpasses - [ ] Exercise 2: All 4 buttons control corresponding LEDs,
make testpasses - [ ] Exercise 3: Truth table filled in, verified on hardware,
make testpasses - [ ] Exercise 4: Active-low pattern implemented and working,
make testpasses - [ ] At minimum: Exercise 3 or 4 programmed on board with logic modifications
Quick Reference¶
All commands run inside the Nix shell (nix develop from the repo
root). Programming and stat targets run from the day directory;
test targets run from inside an exercise's starter/
directory.
cd ~/hdl-for-dsd && nix develop # once per terminal session
# ── from labs/week1_day01/ ──
make ex1 # build and program Exercise 1
make ex2 # build and program Exercise 2
make ex3 # build and program Exercise 3
make ex4 # build and program Exercise 4
make ex5 # build and program Exercise 5 (stretch)
make exN_sim # simulate (uses solution/tb/ if no local tb)
make exN_wave # simulate + open VCD in GTKWave
make ex1_stat # show resource usage for Exercise 1
make clean # remove all build artifacts
# ── from labs/week1_day01/exN_*/starter/ ──
make test # run published self-checking testbench (PASS/FAIL)
make exN SOLUTION=1 (from the day directory) runs the reference DUT
through the full toolchain. It reads from solution/ref/. Plain make exN
against your starter runs your own code.