Barcelona Abroad · Optional Self-Study  🔧 Same hardware, sharper tools

SystemVerilog for Design

Not on the Barcelona calendar — part of the "Keep Going" self-study track (baseline D13)

HDL for Digital System Design · UCF ECE · Barcelona Summer 2026

CRAFT

Today at a Glance

PhaseTimeActivity
🌍 Contextualize10 minSV is what you'll write at a chip company · IEEE 1800 lingua franca
⚠️ Reframe15 minSV = Verilog + guardrails · intent declarations, not new hardware
🛠 Assemble70 minRefactor traffic light FSM · refactor UART TX · enum states · typedef struct
🛡 Fortify45 minPPA before / after must be identical · Verilator lint · 🤖 AI refactor critique
🔗 Transfer10 minPark Güell bridge · D13 SV for verification
Today's promise: the LUT/FF count after SV refactor will be byte-identical to your Verilog. The wins are at compile time, not in silicon.

▸ Phase 1 of 5  ·  ~10 min

🌍 Contextualize

SV is what your first job offer will ask for

SystemVerilog Is Industry's Default

  • Semidynamics — their RISC-V cores ship as SV. Every customer integration assumes logic and always_ff.
  • HP, AMD, Intel, NVIDIA, Apple silicon teams — SV-only RTL flows. Verilog-2001 is what their legacy IP is written in.
  • Every commercial EDA tool — Synopsys VCS, Cadence Xcelium, Siemens Questa — first-class SV support, often Verilog-2001 is the fallback.
  • Open-source too — Verilator's strongest mode is SV. Icarus needs -g2012.

The job market signal

Job posting reality: "Verilog/SystemVerilog" really means "we expect you to write SV; we'll read your Verilog." After today you'll do both.

SV was standardized as IEEE 1800 in 2005. It's not new. What's new is that the open-source tool stack finally supports enough of it for classroom use.

▸ Phase 2 of 5  ·  ~15 min

⚠️ Reframe

Guardrails, not a new language

⚠️ "A Whole New HDL to Learn"

❌ Wrong Model

"SV is to Verilog what C++ is to C — a different language with new paradigms I have to study from scratch."

✓ Right Model

SV is Verilog with guardrails. Five small additions (logic, always_ff, always_comb, enum, typedef) catch 80% of the bugs you've been writing all month.

Your Verilog still compiles under SV. SV is a strict superset. You're adding tools, not switching toolboxes.

Side-by-Side: D-FF

Verilog-2001

module dff (
    input  wire       clk,
    input  wire       d,
    output reg        q
);
    always @(posedge clk)
        q <= d;
endmodule

SystemVerilog

module dff (
    input  logic clk,
    input  logic d,
    output logic q
);
    always_ff @(posedge clk)
        q <= d;
endmodule
  • logic replaces both wire and reg — no more "wait, is this a reg or a wire?" mental tax.
  • always_ff tells the tool "this is a flip-flop" — the compiler errors if you write combinational logic inside.
  • Synthesized hardware: byte-identical. The win is at compile time.

Intent Declarations Catch Latches

// ❌ Verilog: this synthesizes — and creates a latch you didn't want
always @(*) begin
    case (op)
        2'b00: y = a;
        2'b01: y = b;
        // 10, 11 missing — y holds last value → LATCH
    endcase
end
// ✓ SystemVerilog: tool ERRORS at compile time
always_comb begin
    case (op)
        2'b00: y = a;
        2'b01: y = b;
        // → "always_comb infers latch" — STOPS THE BUILD
    endcase
end
always_comb + always_ff = intent. The tool checks your code matches what you meant.

enum States Replace localparam Soup

Verilog

localparam IDLE  = 3'd0;
localparam START = 3'd1;
localparam DATA  = 3'd2;
localparam STOP  = 3'd3;
reg [2:0] state;
// $display("state=%d", state);  // 1, 2, …

SystemVerilog

typedef enum logic [1:0] {
    IDLE, START, DATA, STOP
} state_t;
state_t state;
// $display("state=%s", state.name());
// → "state=START"
  • Width auto-computed — 4 states → 2 bits, no manual count.
  • .name() for debug — readable waveforms, readable logs.
  • Type-safe — assigning an arbitrary integer is an error.

▸ Phase 3 of 5  ·  ~70 min  ·  Refactor & resimulate

🛠 Assemble

Two refactors · one simulation · one PPA check

Build Plan

  1. Ex 1 · 30 min  Refactor traffic light FSM (from D7) — logic, always_ff, always_comb, typedef enum states, $display with .name(). Compile with iverilog -g2012.
  2. Ex 2 · 30 min  Refactor UART TX (from yesterday) — same conversions + a typedef struct packed for UART config (parameter group: CLKS_PER_BIT, parity preview).
  3. Ex 3 · 15 min  Simulate both versions against the same testbench. GTKWave side-by-side. Confirm cycle-identical waveforms.
Ex 4 (10 min): PPA comparison — Verilog vs SV refactor, yosys stat diff.
Ex 5 stretch: create a project-wide uart_pkg with shared typedefs. Import into both modules.

Refactored Traffic Light FSM

module traffic_light (
    input  logic       clk, rst,
    output logic [1:0] light    // 00=R, 01=Y, 10=G
);
    typedef enum logic [1:0] {RED, GREEN, YELLOW} state_t;
    state_t state, next;
    logic [3:0] tick;

    always_ff @(posedge clk) begin
        if (rst) begin state <= RED;  tick <= 0; end
        else if (tick == 4'hF) begin state <= next; tick <= 0; end
        else                        tick <= tick + 1;
    end

    always_comb begin
        next = state;                            // default — no latch
        unique case (state)
            RED:    next = GREEN;
            GREEN:  next = YELLOW;
            YELLOW: next = RED;
        endcase
    end

    always_comb light = (state == RED)    ? 2'b00 :
                        (state == YELLOW) ? 2'b01 : 2'b10;

    always_ff @(posedge clk)
        $display("[%0t] state=%s", $time, state.name());
endmodule

UART Config — typedef struct packed

// Group related config — pass as one signal
typedef struct packed {
    logic [15:0] clks_per_bit;
    logic        parity_en;          // preview: D13 parity exercise
    logic        parity_type;        // 0=even, 1=odd
} uart_cfg_t;

module uart_tx_sv (
    input  logic       clk, rst,
    input  uart_cfg_t  cfg,          // ← one port, three fields
    input  logic       tx_start,
    input  logic [7:0] tx_data,
    output logic       tx_out, tx_busy
);
    typedef enum logic [1:0] {IDLE, START, DATA, STOP} state_t;
    state_t state;
    logic [15:0] baud_cnt;
    logic [2:0]  bit_idx;
    logic [7:0]  data_latched;
    // … FSM body unchanged from yesterday, with logic/always_ff …
endmodule

A single struct packed port replaces 3 separate inputs. Same bits on the wire; cleaner interface.

▸ Phase 4 of 5  ·  ~45 min  ·  Identical hardware · safer source

🛡 Fortify

Prove the refactor is free

PPA Before / After — Should Be Identical

yosys -p "synth_ice40 -top uart_tx;    stat" uart_tx.v        | grep SB_
yosys -p "synth_ice40 -top uart_tx_sv; stat" -sv uart_tx_sv.sv | grep SB_
VersionSB_LUT4SB_DFF*Fmax (MHz)
UART TX — Verilog???
UART TX — SystemVerilog===
If the numbers differ: you changed behavior, not just syntax. Roll back, diff carefully, retry. The whole point of "refactor" is "same hardware."

Lint with Verilator

verilator --lint-only -Wall -sv uart_tx_sv.sv
  • UNUSED / UNDRIVEN — signals declared but never read/written. Free dead-code detection.
  • WIDTHEXPAND / WIDTHTRUNC — implicit width mismatches. The #1 hidden bug in student RTL.
  • LATCH — missing default in always_comb. SV catches this; lint reinforces it.
  • CASEINCOMPLETE — case statement without default. Often a latch waiting to happen.
Run lint on every module from now on. The bugs it finds in 0.3 seconds cost hours in waveform debug.

🤖 Check the Machine — Refactor Prompt

Prompt: "Refactor this Verilog FSM to idiomatic SystemVerilog using logic, always_ff, always_comb, and a typedef enum for states. Keep the hardware identical."

  • Did it use enum for states? Or did it just rename localparams? The point is the type, not the keyword.
  • Did it add a default to the case? Or rely on always_comb to catch the latch later? Both work; defaults are clearer.
  • Did it use unique case or priority case? If it picked one, ask why. (unique = "I promise exactly one match"; priority = "first match wins.")
  • Did it preserve the timing? A common AI miss: collapsing a 2-process FSM into a 1-process one. Different code, different timing. Run PPA on both.

Hardware Verification

  • Traffic light SV: flash to board. Same red/yellow/green cadence as your D7 build. $display in simulation now prints state=RED instead of state=0.
  • UART TX SV: "HELLO" still appears on the terminal. Byte-for-byte identical to yesterday.
  • PPA report committed — Verilog row + SV row, identical counts. Screenshot for the portfolio.
The honest test: can you swap the Verilog module for the SV one in your top file and the board does exactly the same thing? That's the contract.

▸ Phase 5 of 5  ·  ~10 min  ·  Park Güell · then assertions

🔗 Transfer

Parameterization, modularity, and tiles

Park Güell — Modular by Design

Gaudí's trencadís mosaic — broken tiles assembled into modular benches, ceiling medallions, salamander scales. One pattern, parameterized per surface.

A SystemVerilog typedef + parameter + generate is the silicon version of the same idea: repeating units with controlled variation.

Look for it this afternoon

  • Tile shapes that could all be the same — and the ones that aren't.
  • Where parameters express artistic choice (color, size, density).
  • Where Gaudí didn't parameterize — and why.
Reflection prompt: photograph one tile pattern. Describe it as a Verilog/SV generate block in one sentence. Bring to D13.

Next in the Self-Study Track · SV for Verification

This deck fixed how RTL is written. The companion deck fixes how RTL is checked: assertions, constraint-based stimulus, and an AI-generated TB.

Your SV UART from here is the starting point — it gets 5+ assertions and an optional parity extension.

Keep Going

  • 📺 Optional video — assertions, AI verification, PPA methodology (~55 min — dense)
  • 📂 Companion deck: SystemVerilog for Verification (baseline D14)
  • 🛠 Try it on a project module you've already built in required Verilog

🔗 End of the SV-for-Design self-study deck

Same gates. Half the bugs.
That's the SV deal.

You wrote less code, the synth produced the same hardware, the lint caught real bugs.
Next in the track: SV checks the design before the design ships.

CRAFT