Part 1 · Language Foundations · Intermediate
SystemVerilog Language Foundations
The language core every verification engineer must own: types, arrays, procedural code, operators, compilation units, and interfaces — the substrate everything else in SystemVerilog stands on.
What this section covers
Every constraint, covergroup, and class library sits on top of the language core : how values are represented, how data is organized, how procedural code executes, and how source files become an elaborated simulation. Weakness here shows up later as mysterious X bugs, race conditions, and compile-order failures that look unrelated to their root cause.
Each major topic below is a hub page with focused sub-topics. Drill into 4-state vs 2-state semantics , array machinery, always_comb/always_ff procedural rules, operator gotchas, package-based compilation, and the interface/clocking-block layer that connects a class-based testbench to RTL pins.
Topic map
Legend: [TYPE] [DATA] [PROC] [COMP] [IFACE]
┌─────────────────────────────────────────────────────────────────────────┐
│ LANGUAGE FOUNDATIONS — topic map │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. DATA TYPES [TYPE] │
│ 4-state vs 2-state │ nets vs vars │ casting │ X/Z │ enums │ strings │
│ │
│ 2. ARRAYS [DATA] │
│ packed/unpacked │ dynamic │ queues │ assoc │ methods │ foreach │
│ │
│ 3. PROCEDURAL CODE [PROC] │
│ always_comb/ff │ blocking vs NBA │ tasks/functions │ fork-join │
│ │
│ 4. OPERATORS & EXPRESSIONS [TYPE] │
│ reduction │ streaming │ wildcard equality │ precedence │ sizing │
│ │
│ 5. PACKAGES & COMPILATION [COMP] │
│ import │ compilation units │ `include vs import │ elaboration order │
│ │
│ 6. INTERFACES & CLOCKING [IFACE] │
│ modports │ virtual interfaces │ clocking blocks │ TB-DUT timing │
│ │
└─────────────────────────────────────────────────────────────────────────┘Topics and sub-topics
Data Types — 4-state vs 2-state, nets vs variables, integer casting, X/Z propagation, enums/structs/unions, strings and special types.
Arrays — packed vs unpacked layout, dynamic arrays, queues, associative arrays, array methods, and iteration idioms.
Procedural Code — always_comb/always_ff semantics, blocking vs non-blocking assignment, tasks vs functions, fork-join process control.
Operators & Expressions — reduction and streaming operators, ==?/inside, expression sizing rules, and sign-extension traps.
Packages & Compilation — package import vs `include, compilation units, elaboration order, and how simulators build a design.
Interfaces & Clocking — interface bundles, modports, virtual interfaces, and clocking blocks for race-free TB sampling and driving.
How RTL and testbench views differ
SystemVerilog serves two worlds with one language. The RTL world is structural and 4-state: every signal models real hardware, X means unknown silicon state, and Z means an undriven net. The testbench world is software-like and mostly 2-state: classes, queues, int loop counters, and string formatting — performance and convenience matter more than X modeling. Most foundation-level bugs live at the boundary where the two worlds exchange values.
Legend: [TYPE] [IFACE]
4-STATE RTL WORLD 2-STATE CLASS WORLD
───────────────────── ─────────────────────
modules, wires, logic [TYPE] classes, queues, int/bit [TYPE]
values: 0 1 X Z values: 0 1 only
init: X (uninitialized) init: 0 (silently "valid")
X = real unknown silicon state X impossible — converted to 0
static, elaborated structure dynamic, new()-ed at runtime
│ │
└────────────┐ ┌────────────┘
▼ ▼
┌────────────────────────────────┐
│ BOUNDARY [IFACE] │
│ virtual interface + clocking │
│ 4-state ◄──► 2-state copies │
│ X/Z silently become 0 going │
│ into bit/int — check first! │
└────────────────────────────────┘Why the boundary matters
[TYPE] Copying a logic bus carrying X into an int produces 0 — the unknown disappears and the scoreboard happily compares garbage.
[TYPE] 2-state class fields initialize to 0, so a never-assigned field looks like a legal value instead of an obvious X.
[IFACE] Clocking blocks define when the TB samples and drives — without them, TB code races against RTL non-blocking updates.
[TYPE] RTL must stay 4-state so X propagation exposes reset and don't-care bugs that 2-state simulation hides.
Key takeaways
Foundations bugs surface later as X mysteries, races, and compile-order failures — learn the semantics, not just the syntax.
Keep RTL 4-state and testbench transaction fields 2-state; guard the boundary with explicit X/Z checks.
Six topics: data types, arrays, procedural code, operators, packages, interfaces — each is a hub with deep sub-lessons.
Common pitfalls
Treating logic and bit as interchangeable — X-hiding at the TB boundary silently corrupts checks.
Learning class-based SystemVerilog without procedural semantics — race conditions in monitors and drivers follow.
Skipping packages/compilation — works in one-file examples, breaks the moment a real multi-file project is built.