CRAFT cycle · 2.5 hours · Mon 6/1 · PM visit: Semidynamics
HDL for Digital System Design · UCF ECE · Barcelona Summer 2026
| Phase | Time | Activity |
|---|---|---|
| 🌍 Contextualize | 10 min | Counting in the city · Semidynamics framing |
| ⚠️ Reframe | 15 min | delay() ≠ a counter · sim ≠ proof · TBs find bugs |
| 🛠 Assemble | 70 min | Debouncer · LED chase · self-checking TB · AI-generated TB |
| 🛡 Fortify | 45 min | Noisy-input stim · AI TB review · hardware verify |
| 🔗 Transfer | 10 min | Brief for Semidynamics · D7 preview |
▸ Phase 1 of 5 · ~10 min
Every digital system counts, shifts, and debounces
Semidynamics — RISC-V vector processor startup in Barcelona. Ask: how much of their development effort is verification? The answer will reframe today's Fortify phase.
Counters · shift registers · debouncers · testbenches. Four primitives that show up in every commercial design.
▸ Phase 2 of 5 · ~15 min
Two software habits to unlearn today
delay() Is Not Hardware"To wait 10 ms for a button to stop bouncing, call delay(10). It works in Arduino — same idea here."
Hardware doesn't wait — it counts clock cycles. A debouncer is a saturating counter: increment when the input is stable, reset when it changes, output flips only when the counter saturates.
10 ms @ 25 MHz = 250 000 cycles — parameterize the threshold.
"My testbench printed PASS, so my module works."
Simulation only proves correctness for the cases you tested. A TB finds bugs; it cannot prove their absence. The discipline: directed tests for known corners, then sweeps for everything else.
// Apply inputs → wait → compare → report
a = 4'd3; b = 4'd5; op = OP_ADD; #10;
if (y !== 4'd8) begin
$display("FAIL: ADD 3+5 got %0d", y);
fails = fails + 1;
end
// At the end:
if (fails == 0) $display("PASS: %0d tests", tests);
else $display("FAIL: %0d/%0d", fails, tests);
$finish;
!==, not != — catches X/Z$finish, not infinite loops — otherwise the simulator never returns▸ Phase 3 of 5 · ~70 min · You build · you test
Build the DUTs · then build the TBs that prove them
$readmemh stimulus vectors) — preview of Day 9.
module debouncer #(
parameter THRESHOLD = 250_000 // 10 ms @ 25 MHz
)(
input wire clk, rst,
input wire in_async,
output reg out_clean
);
// 2-FF synchronizer
reg s1, s2;
always @(posedge clk) {s2, s1} <= {s1, in_async};
reg [$clog2(THRESHOLD)-1:0] cnt;
always @(posedge clk) begin
if (rst) cnt <= 0;
else if (s2 != out_clean) begin
if (cnt == THRESHOLD-1) begin
out_clean <= s2; // commit
cnt <= 0;
end else cnt <= cnt + 1;
end else cnt <= 0; // reset on noise
end
endmodule
Keep this snippet in your personal library. You'll use it in every project this course.
module led_chase (
input wire clk,
input wire dir, // 1 = left, 0 = right
output reg [3:0] led
);
reg [22:0] tick_cnt;
wire tick = (tick_cnt == 23'd2_500_000 - 1); // ~10 Hz
always @(posedge clk) tick_cnt <= tick ? 0 : tick_cnt + 1;
initial led = 4'b0001;
always @(posedge clk) if (tick) begin
led <= dir ? {led[2:0], led[3]} // rotate left
: {led[0], led[3:1]}; // rotate right
end
endmodule
First design that combines two sequential blocks. This is RTL composition.
Prompt scaffolding (use this as a template — paste DUT interface verbatim):
Generate a self-checking Verilog testbench for this debouncer. Interface: clk, rst, in_async, out_clean. Parameter THRESHOLD (use 8 for sim). Test cases: 1. Reset behavior 2. Stable input -> out_clean follows after THRESHOLD cycles 3. Bouncing input (toggle 5x, then steady) -> out_clean only flips once 4. Glitch shorter than THRESHOLD -> out_clean does NOT change Use $display PASS/FAIL with !== comparisons, $finish at end. Target Icarus Verilog (IEEE 1364-2005). No SystemVerilog features.
iverilog?▸ Phase 4 of 5 · ~45 min · Verify · review · harden
Find the bugs sim missed
// In the TB — make the input misbehave like a real button
initial begin
in_async = 0; #100;
// Bounce: 5 fast toggles
repeat (5) begin in_async = ~in_async; #3; end
in_async = 1; #200; // settle
if (out_clean !== 1'b1) $display("FAIL: clean missed rising edge");
// Glitch test
in_async = 0; #3; in_async = 1; #200; // 3-cycle blip
if (out_clean !== 1'b1) $display("FAIL: glitch passed through");
end
A debouncer that passes a clean unit-step but fails on bounce or glitch is the most common Day-5 bug on hardware.
$dumpfile / $dumpvarsalways #5 clk = ~clk;)#(.THRESHOLD(8)))!== for X/Z safetylogic, assert) that won't compile under iverilog -g20058'b1010_1100, clock out — SO line traces the pattern (GTKWave + on-board LED).make sim should print PASS: N/N across every opcode + edge case.▸ Phase 5 of 5 · ~10 min
Take it to Semidynamics at 16:00
Three questions to answer before you leave the building:
D7 introduces the 3-always-block FSM pattern. State register + next-state logic + output logic — three blocks that map directly to three physical pieces of hardware.
You'll build a traffic light controller — Plaça Catalunya in Verilog — and write the TB to prove every state transition.
Tomorrow afternoon is the HP Customer Center visit. They'll show you AI-assisted product workflows — directly parallel to today's AI testbench thread.
🔗 End of Day 5+6 · Semidynamics 16:00
You can now design parameterized sequential modules and write self-checking testbenches by hand and with AI.
Tomorrow: states — the abstraction that ties sequence to behavior.