An archive of my solutions to HDLBits, a Verilog/RTL practice platform developed by University of Toronto. Working through this self-directed over summer 2026 ahead of first-year Electrical Engineering at the University of Waterloo, as a means to explore my interest and expand my knowledge on RTL design & verification.
All problem sets are organized by topic in their respective folders.
151 / 182 problems complete (83%)
*progress paused for the next few weeks to work on a cool new project 🤫🧏
- RTL fundamentals: combinational and sequential logic, blocking vs. non-blocking assignment semantics, avoiding unintended latch inference
- Datapath building blocks: ripple-carry and carry-select adders, adder-subtractors, BCD arithmetic, multiplexers, priority encoders, population counters
- Finite state machine design: Moore and Mealy machines, one-hot state encoding, hysteresis FSM, edge detection, dual-edge triggered flip-flops
- Shift registers & LFSRs: Galois-style LFSR structure, tap selection for maximal-length sequences
- Parameterized/generative design:
generatefor-loops for scalable adders and BCD chains, reduction operators on wide vectors - Grid-based sequential systems: Conway's Game of Life on a toroidal 16×16 grid, cellular automata (Rule 90/110)
A few problems worth calling out for the design decisions involved rather than being pure syntax exercises:
- 32-bit LFSR: Galois-style LFSR structure, choosing correct tap positions for a maximal-length sequence.
- 12-hour clock: multi-field state (hours/minutes/seconds) with carry logic between fields and edge cases at 12:59:59 → 1:00:00.
- Conway's Game of Life (16×16 toroidal): implemented the full birth/survival/death rule set on a 256-cell grid, with wrap-around (toroidal) neighbor indexing so edge and corner cells correctly reference neighbors on the opposite side of the board using combinational arithmetic. The trickiest part was updating all 256 cells simultaneously on a single clock edge: computing each cell's next state requires reading the current state of its 8 neighbors, so the whole grid has to be treated as one snapshot rather than updated cell-by-cell. This meant being deliberate about blocking vs. non-blocking assignment. Thus, using non-blocking (<=) throughout the update logic to make sure every cell computes its next state from the same consistent snapshot of the board, rather than accidentally reading a neighbor's already-updated value mid-cycle.
- Designing a Moore FSM for Water Reservoir Hysteresis Controller: a 6-state Moore machine overcoming a directional state-tracking problem. Utilizes vector to map physical sensor logic directly to state names, implementing directional tracking (rising vs. falling) to drive a supplemental flow rate valve (ΔFR) only when the level drops, and drive three distinct nominal flow rate outputs (FR1, FR2, FR3) when the level rises.
Solutions are organized to mirror HDLBits' own categories, so it's easy to cross-reference against the site.
| Section | Status |
|---|---|
| Getting Started | ✅ Completed |
| Verilog Language (Basics, Vectors, Modules, Procedures, More Features) | ✅ Completed |
| Circuits — Combinational Logic (Basic Gates, Multiplexers, Arithmetic Circuits, Karnaugh Map to Circuit) | ✅ Completed |
| Circuits — Sequential Logic (Latches/FFs, Counters, Shift Registers) | ✅ Completed |
| Circuits — More Circuits (Cellular Automata) | ✅ Completed |
| Circuits — Finite State Machines | ✅ Completed |
| Circuits — Building Larger Circuits | 🔄 In progress |
| Verification — Reading Simulations | ⬜ Not started |
| Verification — Writing Testbenches | ⬜ Not started |
Basics
Vectors
- Vectors
- Vectors in more detail
- Vector part select
- Bitwise operators
- Four-input gates
- Vector concatenation operator
- Vector reversal 1
- Replication operator
- More replication
Modules: Hierarchy
- Modules
- Connecting ports by position
- Connecting ports by name
- Three modules
- Modules and vectors
- Adder 1
- Adder 2
- Carry-select adder
- Adder-subtractor
Procedures
- Always blocks (combinational)
- Always blocks (clocked)
- If statement
- If statement latches
- Case statement
- Priority encoder
- Priority encoder with casez
- Avoiding latches
More Verilog Features
- Conditional ternary operator
- Reduction operators
- Reduction: Even wider gates
- Combinational for-loop: Vector reversal 2
- Combinational for-loop: 255-bit population count
- Generate for-loop: 100-bit binary adder 2
- Generate for-loop: 100-digit BCD adder
Basic Gates
- Wire
- GND
- NOR
- Another gate
- Two gates
- More logic gates
- 7420 chip
- Truth tables
- Two-bit equality
- Simple circuit A
- Simple circuit B
- Combine circuits A and B
- Ring or vibrate?
- Thermostat
- 3-bit population count
- Gates and vectors
- Even longer vectors
Multiplexers
- 2-to-1 multiplexer
- 2-to-1 bus multiplexer
- 9-to-1 multiplexer
- 256-to-1 multiplexer
- 256-to-1 4-bit multiplexer
Arithmetic Circuits
- Half adder
- Full adder
- 3-bit binary adder
- Adder
- Signed addition overflow
- 100-bit binary adder
- 4-digit BCD adder
Karnaugh Map to Circuit
- 3-variable
- 4-variable
- 4-variable
- 4-variable
- Minimum SOP and POS
- Karnaugh map
- Karnaugh map
- K-map implemented with a multiplexer
Latches and Flip-Flops
- D flip-flop
- D flip-flops
- DFF with reset
- DFF with reset value
- DFF with asynchronous reset
- DFF with byte enable
- D Latch
- DFF
- DFF
- DFF+gate
- Mux and DFF
- Mux and DFF
- DFFs and gates
- Create circuit from truth table
- Detect an edge
- Detect both edges
- Edge capture register
- Dual-edge triggered flip-flop
Counters
- Four-bit binary counter
- Decade counter
- Decade counter again
- Slow decade counter
- Counter 1-12
- Counter 1000
- 4-digit decimal counter
- 12-hour clock
Shift Registers
- 4-bit shift register
- Left/right rotator
- Left/right arithmetic shift by 1 or 8
- 5-bit LFSR
- 3-bit LFSR
- 32-bit LFSR
- Shift register
- Shift register
- 3-input LUT
More Circuits (Cellular Automata)
Finite State Machines
- Simple FSM 1 (asynchronous reset)
- Simple FSM 1 (synchronous reset)
- Simple FSM 2 (asynchronous reset)
- Simple FSM 2 (synchronous reset)
- Simple state transitions 3
- Simple one-hot state transitions 3
- Simple FSM 3 (asynchronous reset)
- Simple FSM 3 (synchronous reset)
- Design a Moore FSM
- Lemmings 1
- Lemmings 2
- Lemmings 3
- Lemmings 4
- One-hot FSM
- PS/2 packet parser
- PS/2 packet parser and datapath
- Serial receiver
- Serial receiver and datapath
- Serial receiver with parity checking
- Sequence recognition
- Q8: Design a Mealy FSM
- Q5a: Serial two's complementer (Moore FSM)
- Q5b: Serial two's complementer (Mealy FSM)
- Q3a: FSM
- Q3b: FSM
- Q3c: FSM logic
- Q6b: FSM next-state logic
- Q6c: FSM one-hot next-state logic
- Q6: FSM
- Q2a: FSM
- Q2b: One-hot FSM equations
- Q2a: FSM
- Q2b: Another FSM
- Building Larger Circuits
- Verification: Reading Simulations
- Verification: Writing Testbenches
All solutions here were simulated successfully virtually with ModelSim and synthesized successfully with Altera Quartus.
Solutions by Zhiyuan (Jerry) Jiang
Problem sets and resources by HDLbits
