SystemVerilog (IEEE 1800) adds features that let designers state intent so tools can check it. For an equivalent rewrite of the same logic, the synthesized hardware is unchanged, but common mistakes become compile-time errors or warnings instead of silent bugs.
Verilog-2001 habit | SystemVerilog replacement | What the tool can now check |
|---|---|---|
|
| Clear 4-state data typing; process keywords and lint check writer ownership. |
|
| Combinational intent; automatic sensitivity and single-writer rule, with latch checks to enable and review. |
|
| The block really is edge-triggered storage. |
|
| Typed states; unhandled values are visible. |
|
| Overlap and missing-case conditions can be checked in simulation when the checks are enabled. |
Long bus port lists |
| Direction mismatches at the connection. |
6 lessons, about 27 min
For an equivalent rewrite such as the counter in Why SystemVerilog improves RTL quality, no. It changes how clearly you express the hardware and how much the tools can check. The same logic comes out and fewer bugs make it there. Unique and priority assumptions can change what synthesis builds; the later lesson covers them.
The whole topic on one page, taken from each lesson's Remember box. Read it before an interview, or print it.
Why SystemVerilog Improves RTL Quality
The fill literals '0, '1, 'x and 'z take the width of the target, which keeps parameterised code correct.
Start with the cheap wins: logic, always_ff, always_comb and typedef enum.
Classes, constrained randomisation and mailboxes are verification constructs, not RTL.
Rule of thumb: turn on lint so intent violations are reported on every compile.
The `logic` Type and Assignment Model
logic is 4-state and starts as x, so an un-reset flop shows x in the waveform.
logic alone does not enforce one writer. Use always_ff and always_comb with lint to check ownership.
An x in an if condition is false. Compare with === and !== in testbenches.
Rule of thumb: one writer per RTL variable, and a net for anything shared.
always_ff and always_comb
Each block type is a promise the tool checks: clocked, combinational or latch.
A latch comes from an output not assigned on some path. Fix it with a default assignment or an else branch.
unique promises exactly one match and priority promises at least one. Synthesis uses the promise, so keep it exact.
Rule of thumb: one signal, one process.
typedef, enum and Robust FSM Coding
A typedef enum names the states and stops arbitrary constants reaching the state register.
Put next = state; and the output defaults at the top of always_comb.
The default branch recovers in RTL. Synthesis may re-encode or drop it, so check the gate netlist.
Rule of thumb: reset to a known state and send every illegal state somewhere safe.
Interfaces and Modports
A modport states direction: a connection against it is a compile error in a tool that enforces it.
For a link of two or three signals used in one place, a plain port list is simpler.
Interface support in synthesis, lint and CDC tools varies. Test the whole flow on a small example first.
Rule of thumb: bring in interfaces last, after the team agrees on connection and verification.
SystemVerilog RTL Cheat Sheet
always_ff for storage with <=, always_comb with defaults first and =, logic, typed enums, and unique or priority case with a default.
One unsigned operand makes the expression unsigned, a narrow target drops the carry, and >>> keeps the sign only on a signed operand.
Keep initial, # delays, casex, implicit nets, full_case pragmas and === out of synthesisable code.
Rule of thumb: if the code depends on a width, a sign or an unknown, write it explicitly and test it with a value that would expose it.
Mini project: a 4-bit ALU with flags and an exhaustive bench
Practice question: Level-sensitive latch: why it is risky and how to code it safely
Practice question: FSM incomplete case and unique0: simulation vs synthesis
Practice question: FSM design with enums and unique/priority case
Code lab: Build a signed comparator
Interview: run a mock interview on this topic