Not on the Barcelona calendar — part of the "Keep Going" self-study track (baseline D14)
HDL for Digital System Design · UCF ECE · Barcelona Summer 2026
| Phase | Time | Activity |
|---|---|---|
| 🌍 Contextualize | 10 min | Assertions = executable specs · verif eng writes them before RTL |
| ⚠️ Reframe | 15 min | Testing isn't at the end · assertions live inside the design |
| 🛠 Assemble | 70 min | Assertions on UART TX · parity via generate if · 🤖 AI TB for project module |
| 🛡 Fortify | 45 min | Bug injection · coverage analysis · structured PPA report |
| 🔗 Transfer | 10 min | How this fits the required course · Keep Going track |
▸ Phase 1 of 5 · ~10 min
In industry, verification writes the spec
Most chips are 70%+ verification cost. The verif engineers who write good assertions are the ones who keep the line moving.
Today you take the first step into that role.
An assertion that never fires might mean your design is correct — or that your TB never exercised that path. Coverage tells you which.
▸ Phase 2 of 5 · ~15 min
Assertions live inside the design
"I'll finish the RTL, then write a TB at the end. If sim passes, I ship."
Assertions are inline with your RTL. They fire the instant something violates the contract. They're not "tests at the end" — they're contracts that ride with the design forever.
always_ff @(posedge clk) begin
// Contract: TX line idles high
assert (state != IDLE || tx_out == 1'b1)
else $error("TX low while IDLE at t=%0t", $time);
// Contract: bit_idx in range during DATA state
assert (state != DATA || bit_idx < 8)
else $fatal("bit_idx overflow: %0d", bit_idx);
// Contract: no new tx_start accepted while busy
assert (!(tx_busy && tx_start))
else $error("tx_start while busy — protocol violation");
end
$error = sim continues, fail recorded. Good for non-fatal contract violations.$fatal = sim stops. Good for "we cannot continue — something is corrupt."| Level | What it looks like | You at… |
|---|---|---|
| 1 · Manual | "Looks right in GTKWave" → ship | Day 1 |
| 2 · Self-checking | TB with PASS/FAIL printout | Day 5/6 |
| 3 · AI-scaffolded | AI generates TB; you correct + audit | Day 6 onward |
| 4 · Assertion-enhanced | Contracts inline in RTL | Today (Ex 1) |
| 5 · Constraint-driven | Constrained random + AI stimulus | Today (Ex 3) |
| 6 · Coverage-driven | Coverpoints + bins + closure | Industry / preview today |
▸ Phase 3 of 5 · ~70 min · Contracts · parity · project TB
Three deliverables · capstone Fortify
generate if) — PARITY_EN & PARITY_TYPE parameters. Conditionally insert a parity bit in the frame. Skippable if you're behind on your project.// Intentionally swap start/stop polarity
START: begin tx_out <= 1'b1; // ❌ was 1'b0 — START should be LOW
// …
end
Re-run the existing TB. Assertion fires:
"START bit must be 0 at t=170 — got 1" ASSERTION FAILED in uart_tx.sv:34 $finish called from sim — 1 error, 0 warnings
generate ifmodule uart_tx_sv #(
parameter int CLKS_PER_BIT = 217,
parameter bit PARITY_EN = 0,
parameter bit PARITY_TYPE = 0 // 0=even, 1=odd
)(/* ports */);
logic parity_bit;
generate
if (PARITY_EN) begin : gen_parity
// Even parity: XOR reduction; flip if odd
always_comb parity_bit = (^tx_data) ^ PARITY_TYPE;
// FSM: IDLE → START → DATA(8) → PARITY → STOP
end else begin : gen_no_parity
assign parity_bit = 1'b0; // unused, optimized away
// FSM: IDLE → START → DATA(8) → STOP
end
endgenerate
endmodule
Compile two variants, run yosys stat on both. Question: how many LUTs does one parity bit cost?
Prompt template: "Generate a self-checking SV testbench for <your project module>. Constraint: stimulate <input X> in range [A, B], <input Y> covering <legal values>. Include ≥10 random cases per input combo. Use $urandom_range(). Add a scoreboard tracking PASS/FAIL counts. Print final coverage as `tests_run / cases_seen`."
▸ Phase 4 of 5 · ~45 min · Coverage · PPA · structured report
Numbers + paragraphs · the final-project rubric
| Variant | LUTs | FFs | Fmax | Notes |
|---|---|---|---|---|
Mult — combinational * | ? | 0 | ? | 1 cyc · D10 |
| Mult — shift-and-add | ? | ? | ? | 8 cyc · D10 |
| UART TX — PARITY_EN=0 | ? | ? | ? | 10-bit frame |
| UART TX — PARITY_EN=1 | ? | ? | ? | 11-bit · today |
| Your project module | ? | ? | ? | baseline |
rst mid-operation and check recovery?▸ Phase 5 of 5 · ~10 min · Where this fits
From this room to silicon
D5+6 You already write self-checking and AI-generated testbenches in plain Verilog — that's the required foundation.
D10 The structured PPA report (LUT/FF/Fmax + analysis paragraphs) is already part of the required arc.
SV track Assertions, coverage, and constraint-random stimulus are the next layer up — what this deck adds on top of what you already do.
| UART RX + loopback | 16× oversampling, frame detection, TX→RX echo (baseline D12) |
| SPI Master | Clock polarity/phase, FSM-driven shifting, talking to a real sensor |
| UVM & constraint-random | The industry methodology these SV assertions and coverage lead into |
| Formal verification | Proving a property holds for all inputs, not just tested cases |
In two sentences: name one assertion that would catch a bug a directed testbench might miss. That's the value SV verification adds.
🔗 End of the SV-for-Verification self-study deck
Not required for the Barcelona edition — but the on-ramp to UVM, formal, and a verification-engineer-shaped portfolio.
Pick it up when you're ready.