Project 6: D Flip-Flop: The Building Block of Memory
Implement a D flip-flop with reset and enable and verify its timing.
Quick Reference
| Attribute | Value |
|---|---|
| Difficulty | Beginner |
| Time Estimate | 2-3 hours |
| Main Programming Language | Verilog (Alternatives: VHDL, SystemVerilog) |
| Alternative Programming Languages | VHDL, SystemVerilog |
| Coolness Level | Low |
| Business Potential | Low |
| Prerequisites | Clocked logic, Non-blocking assignments |
| Key Topics | Flip-flops, Reset, Enable |
1. Learning Objectives
- Model edge-triggered storage
- Use reset and enable correctly
- Read timing waveforms
2. All Theory Needed (Per-Concept Breakdown)
Flip-Flops and Registers
Description/Expanded Explanation of the concept
Flip-flops are the fundamental storage elements in synchronous digital logic. A register is a collection of flip-flops that store multi-bit values. Correct usage requires edge-triggered logic and non-blocking assignments.
Definitions & Key Terms
- Flip-flop -> edge-triggered storage element
- Register -> N-bit storage built from flip-flops
- Reset -> initializes state to known values
Mental Model Diagram (ASCII)
clk edge -> [FF] -> q

How It Works (Step-by-Step)
- On each clock edge, the flip-flop samples D.
- The output Q holds the sampled value until the next edge.
- Reset forces Q to a known value.
Minimal Concrete Example
always @(posedge clk) begin
if (reset) q <= 0;
else q <= d;
end
Common Misconceptions
- “reg always means storage.” -> It is a variable that may infer storage.
- “Blocking assignments are fine for registers.” -> Use non-blocking.
Check-Your-Understanding Questions
- Why is non-blocking used for sequential logic?
- What is the difference between a latch and a flip-flop?
- What is the role of reset?
Where You’ll Apply It
- This project: used in Section 3.2 and Section 4
- Also used in: P07-4-bit-updown-counter-with-load.md, P08-shift-register-led-chaser.md
Verification with Testbenches and Waveforms
Description/Expanded Explanation of the concept
Testbenches are simulation-only modules that apply stimulus and check outputs. Waveforms (VCD) are the hardware engineer’s microscope; they reveal timing, glitches, and ordering problems. A good testbench is deterministic and covers edge cases.
Definitions & Key Terms
- Testbench -> a non-synthesizable module that drives a DUT
- VCD -> Value Change Dump waveform file
- Deterministic test -> same inputs produce same outputs every run
Mental Model Diagram (ASCII)
[Testbench] -> [DUT] -> [VCD] -> [GTKWave]

How It Works (Step-by-Step)
- Initialize inputs to known values.
- Apply stimulus over time.
- Dump waveforms and check outputs.
- Add assertions or PASS/FAIL messages.
Minimal Concrete Example
initial begin
$dumpfile("wave.vcd");
$dumpvars(0, tb);
a = 0; b = 1; #10;
$finish;
end
Common Misconceptions
- “If it simulates once, it’s correct.” -> Cover all relevant cases.
- “Waveforms are optional.” -> They are often the only way to debug timing.
Check-Your-Understanding Questions
- Why keep testbench and DUT separate?
- What is the purpose of
$dumpvars? - How do you make a testbench deterministic?
Where You’ll Apply It
- This project: used throughout Section 6 (testing)
- Also used in: all other projects in this folder
3. Project Specification
3.1 What You Will Build
A D flip-flop with synchronous reset and enable plus a testbench.
3.2 Functional Requirements
- Requirement 1: Update Q only on clock edges
- Requirement 2: Reset Q to known value
- Requirement 3: Hold Q when enable is low
3.3 Non-Functional Requirements
- Performance: Stable operation at the target clock and interfaces.
- Reliability: Deterministic outputs on all defined inputs.
- Usability: Clear ports and documented behavior.
3.4 Example Usage / Output
{p['example_usage']}
3.5 Data Formats / Schemas / Protocols
{p[‘data_format’]}
3.6 Edge Cases
- Reset asserted mid-cycle
- Enable low
3.7 Real World Outcome
3.7.1 How to Run (Copy/Paste)
vvp dff_tb
3.7.2 Golden Path Demo (Deterministic)
Run the demo command above with the provided testbench and confirm the outputs match the golden transcript.
3.7.3 CLI Transcript
t=0 reset=1 q=0
t=10 d=1 en=1 q=1
3.7.4 Failure Demo (Expected)
# Example failure case
ERROR: Output mismatch at vector 3
Expected: 0x0A, Got: 0x0B
EXIT CODE: 1
Notes:
- Exit code 0 indicates all tests passed
- Exit code 1 indicates a test failure
4. Solution Architecture
4.1 High-Level Design
[inputs] -> [core logic] -> [outputs]

4.2 Key Components
| Component | Responsibility |
|---|---|
| dff | Clocked storage element |
4.3 Data Structures (No Full Code)
// Example signals (adapt to your design)
reg [7:0] state_reg;
reg [7:0] data_reg;
4.4 Algorithm Overview
Key Algorithm: Core control flow
- Initialize state/reset conditions.
- Apply inputs and compute outputs.
- Update state on clock edges (if sequential).
Complexity Analysis:
- Time: O(1) per cycle
- Space: O(N) for registers and logic
5. Implementation Guide
5.1 Development Environment Setup
iverilog -v
# Ensure GTKWave is installed for waveform viewing
5.2 Project Structure
project-root/
|-- src/
| |-- top.v
| |-- core.v
|-- tb/
| |-- tb.v
|-- Makefile
|-- README.md

5.3 The Core Question You’re Answering
“How does hardware remember a value from one clock edge to the next?”
5.4 Concepts You Must Understand First
- Clocked logic
- Non-blocking assignments
5.5 Questions to Guide Your Design
- Do you prefer sync or async reset?
- What happens if reset deasserts near the clock edge?
5.6 Thinking Exercise
Draw clk, d, en, reset, q and predict q at each edge.
5.7 The Interview Questions They’ll Ask
- Why use non-blocking assignments?
- Latch vs flip-flop?
5.8 Hints in Layers
- Start with always @(posedge clk).
- Add reset first, then enable.
5.9 Books That Will Help
| Topic | Book | Chapter |
|---|---|---|
| Sequential logic | Digital Design and Computer Architecture | Ch. 3 |
5.10 Implementation Phases
Phase 1: Foundation
Goals:
- Establish core module structure
- Implement minimal behavior
Tasks:
- Scaffold module ports and internal signals
- Write a minimal testbench that compiles
Checkpoint: Simulation runs without errors
Phase 2: Core Functionality
Goals:
- Implement full logic
- Verify edge cases
Tasks:
- Complete core logic
- Add directed tests for edge cases
Checkpoint: All tests pass and waveforms match expectations
Phase 3: Polish & Edge Cases
Goals:
- Improve readability
- Document behavior
Tasks:
- Add comments and README notes
- Expand tests for unusual inputs
Checkpoint: Design is deterministic and documented
5.11 Key Implementation Decisions
| Decision | Options | Recommendation | Rationale |
|---|---|---|---|
| Reset strategy | Sync / Async | Sync | Simpler timing closure |
| Test coverage | Directed / Exhaustive | Exhaustive for small logic | Prevents missed cases |
6. Testing Strategy
6.1 Test Categories
| Category | Purpose | Examples |
|---|---|---|
| Unit Tests | Test core logic | Small vectors |
| Integration Tests | Test modules together | Full system |
| Edge Case Tests | Boundary conditions | Max/min values |
6.2 Critical Test Cases
- Test 1: Confirm q updates only on edges
- Test 2: Confirm reset overrides d
6.3 Test Data
Use deterministic vectors and document expected outputs.
7. Common Pitfalls & Debugging
7.1 Frequent Mistakes
| Pitfall | Symptom | Solution |
|---|---|---|
| Combinational assignment | Q changes between edges | Move logic into clocked block |
7.2 Debugging Strategies
- Inspect waveforms at key internal signals
- Add temporary debug outputs to verify state
- Reduce testcases to the smallest failing case
7.3 Performance Traps
- Overly wide counters or combinational paths can reduce max clock
8. Extensions & Challenges
8.1 Beginner Extensions
- Add parameterization for widths
- Add optional features (enable, reset)
8.2 Intermediate Extensions
- Add configuration registers
- Build a simple driver or demo program
8.3 Advanced Extensions
- Integrate with another project in this series
- Implement a hardware demo on FPGA
9. Real-World Connections
9.1 Industry Applications
- Digital control systems and embedded peripherals
- FPGA prototyping and validation
9.2 Related Open Source Projects
- Yosys / nextpnr toolchain for open-source FPGA flow
- Example HDL projects in the FPGA community
9.3 Interview Relevance
- Demonstrates RTL thinking and verification skills
10. Resources
10.1 Essential Reading
- Digital Design and Computer Architecture - Focus on Ch. 3
10.2 Video Resources
- Search for project-specific HDL walkthroughs and waveforms
10.3 Tools & Documentation
- Icarus Verilog
- GTKWave
10.4 Related Projects in This Series
- See adjacent projects in
VERILOG_FROM_ZERO_PROJECTS/
11. Self-Assessment Checklist
11.1 Understanding
- I can explain the core concept without notes
- I can predict waveform behavior for basic inputs
11.2 Implementation
- All functional requirements are met
- All tests pass
- Edge cases are documented
11.3 Growth
- I can explain this project in an interview
- I documented at least one lesson learned
12. Submission / Completion Criteria
Minimum Viable Completion:
- Functional requirements implemented
- Testbench passes
- Waveforms inspected
Full Completion:
- All minimum criteria plus
- Edge cases covered and documented
Excellence (Going Above & Beyond):
- Hardware demo on FPGA
- Clear write-up of lessons learned
Appendix A: Deep Dive Walkthrough
A.1 Signal Map and Invariants
- Inputs:
clk,reset,d - Output:
q
Invariant: q only changes on the active clock edge (or immediately on async reset).
A.2 Timing Sketch
clk: _/\_/\_/\_/\_
d : 0__11____0__
q : 0__11____0__ (updates on rising edges)

A.3 Reset Semantics (Choose One)
- Synchronous: reset sampled on posedge
clk. - Asynchronous: reset in sensitivity list, immediate update.
Document your choice and verify with a dedicated test.
A.4 Deterministic Test Sequence
- Hold reset high for 2 cycles -> expect
q=0. - Deassert reset, drive
d=1before edge ->qbecomes 1 on next edge. - Toggle
dmid-cycle ->qunchanged until edge.
A.5 Debugging Tip
If q glitches, you likely used blocking assignments or mixed reset logic.
13. Deep Dive Appendix
13.1 Timing and Resource Budget
- Flip-flops sample on the clock edge and ignore changes between edges.
- Respect setup/hold around the clock edge; violating them causes metastability.
- In FPGA, a DFF is a native resource, so timing is dominated by the input path.
13.2 Waveform Interpretation Guide
- Q should change only on rising edges of clk.
- Reset should force Q to a known state immediately (async) or at the next clock (sync).
- If Q toggles without a clock edge, you accidentally built a latch.
Example timeline:
clk: _/\_/\_/\_
d: 0 1 0 1
q: 0 1 1 0 (changes only at edges)
13.3 Hardware Bring-Up Notes
- Use a slow clock (divider) so you can see Q changes on LEDs.
- Tie D to a switch and Q to an LED.
- If using a button for reset, debounce it or expect multiple resets.
13.4 Alternate Implementations and Trade-offs
- Add an enable (clock gating or mux on D) to control updates.
- Implement a T flip-flop by feeding
D = ~Q. - Implement a JK flip-flop to explore classic sequential logic.
13.5 Additional Exercises
- Build an 8-bit register from 8 DFFs.
- Add sync vs async reset variants and compare waveforms.
- Build a pulse-stretching circuit using a DFF and combinational logic.