Portfolio case study: verified FPGA systems and evidence
A 1-bit full adder and a 4-bit ripple-carry adder in VHDL, verified in simulation and on real hardware (Digilent Basys 3, Artix-7 XC7A35T). The design was validated three ways:
- On silicon — the full adder synthesized, implemented and programmed onto the Basys 3; all eight truth-table rows verified with switches/LEDs.
- In Vivado — behavioral simulation of the 4-bit adder over ten stimulus vectors, 0–1000 ns (waveforms below).
- Reproducibly, in CI — self-checking GHDL testbenches replay the lab's recorded vectors and sweep all 512 input combinations exhaustively, on every push. No Vivado license needed to verify this repository.
S = A ⊕ B ⊕ Cin
Cout = (Cin · (A + B)) + (A · B)
The carry-out is the majority function of the three inputs, factored to share
the (A or B) term. Implemented behaviorally in
src/full_adder.vhd — two concurrent signal
assignments, no process needed for pure combinational logic.
| Cin | B | A | Cout | S | Decimal |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 | 1 | 1 |
| 0 | 1 | 0 | 0 | 1 | 1 |
| 0 | 1 | 1 | 1 | 0 | 2 |
| 1 | 0 | 0 | 0 | 1 | 1 |
| 1 | 0 | 1 | 1 | 0 | 2 |
| 1 | 1 | 0 | 1 | 0 | 2 |
| 1 | 1 | 1 | 1 | 1 | 3 |
src/ripple_adder.vhd instantiates the same
full_adder component four times and chains the carries — the classic
demonstration of modular design and hierarchy:
flowchart LR
Cin((Cin)) --> FA0
subgraph ripple_adder
FA0["FA0<br/>A(0) B(0)"] -- c01 --> FA1["FA1<br/>A(1) B(1)"]
FA1 -- c12 --> FA2["FA2<br/>A(2) B(2)"]
FA2 -- c23 --> FA3["FA3<br/>A(3) B(3)"]
end
FA0 --> S0((S0))
FA1 --> S1((S1))
FA2 --> S2((S2))
FA3 --> S3((S3))
FA3 --> Cout((Cout))
The trade-off is deliberate: a ripple-carry adder is the smallest possible adder in LUTs, at the cost of a carry path that grows linearly with width — each stage cannot settle until the previous stage's carry arrives. That carry-propagation behavior is exactly what the exhaustive testbench exercises.
brew install ghdl # or apt-get install ghdl
./scripts/run-sim.sh # add --wave for GTKWave dumpsThe suite runs three benches:
| Bench | Checks |
|---|---|
full_adder_check_tb |
all 8 truth-table rows, both outputs asserted |
ripple_adder_check_tb |
the 10 vectors recorded in the lab plus an exhaustive 512-case sweep against numeric addition |
ripple_adder_tb |
the original Vivado stimulus (0–1000 ns), for waveform inspection |
full_adder: all 8 truth-table rows verified.
ripple_adder: all 10 recorded lab vectors verified.
ripple_adder: exhaustive 512-case sweep verified.
| A | B | Cout | S | Sum |
|---|---|---|---|---|
| 0000 (0) | 0001 (1) | 0 | 0001 | 1 |
| 0010 (2) | 0010 (2) | 0 | 0100 | 4 |
| 0011 (3) | 0101 (5) | 0 | 1000 | 8 |
| 0110 (6) | 0111 (7) | 0 | 1101 | 13 |
| 0111 (7) | 0011 (3) | 0 | 1010 | 10 |
| 1010 (10) | 0001 (1) | 0 | 1011 | 11 |
| 1001 (9) | 0110 (6) | 0 | 1111 | 15 |
| 1100 (12) | 1100 (12) | 1 | 1000 | 24 |
| 1011 (11) | 0011 (3) | 0 | 1110 | 14 |
| 1111 (15) | 1111 (15) | 1 | 1110 | 30 |
Note the last three rows: Cout becomes the fifth bit of the answer
(12 + 12 = 24 = 1 1000₂), which is the whole point of bringing the final
carry out of the module.
Vivado waveforms from the original run:
| Buses collapsed | Buses expanded |
|---|---|
![]() |
![]() |
The 1-bit full adder was programmed onto the board with inputs on slide
switches and outputs on LEDs (constraints/basys3.xdc):
| Signal | Board control | Pin |
|---|---|---|
| A | SW0 | V17 |
| B | SW1 | V16 |
| Cin | SW2 | W16 |
| S | LD0 | U16 |
| Cout | LD1 | E19 |
All eight switch combinations reproduced the truth table on the LEDs,
including the two spot-checked carry cases: 1+0+1 = 10₂ (LD1 on, LD0 off)
and 1+1+1 = 11₂ (both on).
Vivado flow: create project (Basys 3 / XC7A35T-1CPG236C) → add src/ and
constraints/basys3.xdc with full_adder as top → synthesize → implement →
generate bitstream → program via Hardware Manager.
├── src/ synthesizable VHDL (full_adder, ripple_adder)
├── constraints/ Basys 3 pin constraints (XDC)
├── sim/ testbenches — self-checking + original Vivado stimulus
├── scripts/ GHDL simulation runner
├── docs/
│ ├── diagrams/ architecture schematics (SVG)
│ └── waveforms/ Vivado behavioral-simulation captures
└── .github/ CI: full verification suite on every push
MIT

