Day 21 — SystemVerilog Data Types
Compare 2-state and 4-state types, model packed and unpacked data, and debug signedness/casting.
Concept lesson
Understand the language feature before coding
Day 21 — SystemVerilog Language: Data Types
Simulation status (28 Oct 2026): The commands below pass on Icarus Verilog 12. Use Icarus for this day: Verilator 5.052 is two-state (X and Z become 0 or 1), so its run stops at the four-state check. Details: Week 5 validation record (VALIDATION.md).
Time: Theory 2 h + guided 2 h + independent 2 h + debug/assignment 1 h.
Workspace: project_workspace/week5_systemverilog/day21_data_types
Guided experiments (1–5)
logicvsbitinitialization and X/Z behavior.- 2-state/4-state equality and case equality.
- Packed vectors and bit selection.
- Unpacked arrays and indexed access.
- Multidimensional arrays.
Independent experiments (6–10)
typedefaliases.- Signed and unsigned values.
- Width truncation and explicit casting.
stringbasics.- Typed packet fields.
Run and capture evidence
mkdir -p sim logs
iverilog -g2012 -Wall -o sim/day21.vvp tb/day21_types.sv
vvp sim/day21.vvp | tee logs/day21.log
These commands pass on Icarus Verilog 12. Record your simulator version with the log, and do not claim completion if compilation fails.
Debug task
Reproduce the deliberately wrong 4-bit cast of 8'hF3; explain the truncation and replace it with the intended width. Attach before/after values and PASS evidence. Convert a Verilog TB data model into typed SystemVerilog declarations.
Deliverable: SV datatype exercise set, log, debug note, and explanation of 2-state vs 4-state behavior.
Language boundary and package fundamentals
SystemVerilog extends Verilog; it does not make every construct synthesizable.
Modules and a supported RTL subset describe hardware. Classes, constrained
randomization, mailboxes, and covergroups are verification facilities. The
extension .sv alone does not select a language version: use the simulator's
SystemVerilog mode and record its version. Synthesis support still depends on
the tool and the construct.
Choose a 4-state type such as logic for signals where x and z are useful
debug evidence. A 2-state bit cannot preserve an unknown value; it is useful
for testbench bookkeeping when unknown detection is not needed. Don't replace
a DUT-facing logic signal with bit just to make an initialization warning
disappear.
SystemVerilog also provides process forms that state the intended hardware:
| Form | Intended behavior | Review point |
|---|---|---|
always_comb |
Combinational logic with automatically derived sensitivity. | Assign every output on every path; inspect latch diagnostics. |
always_ff |
Edge-triggered state. | Use a clear clock/reset event and one procedural owner for each variable. |
always_latch |
Level-sensitive storage when a latch is intentional. | Make the enable and retained-value behavior explicit. |
These forms improve intent checking; they do not make incorrect logic correct, and support depends on the selected SystemVerilog mode and tool.
unique, unique0, and priority can document selection assumptions and
enable run-time diagnostics. Use them only when the specification supports the
assumption: unique expects exactly one matching choice, unique0 allows no
match but expects at most one, and priority expects a matching choice. Keep
safe defaults and explicit error behavior where required. Overlapping
wildcard branches, unknown values, or a synthesis tool's optimization of
assumed-unreachable cases can make an incorrect assumption costly; test those
boundaries instead of treating the keyword as functional coverage.
A package gives related type and helper declarations a named scope. Compile the package before files that use it, then either qualify a name or import it:
package protocol_types;
typedef enum logic [1:0] {IDLE, ACTIVE} state_t;
endpackage
module state_check;
import protocol_types::*;
state_t state;
initial begin
state = IDLE;
if (state != IDLE) $fatal(1, "package type check failed");
$display("PACKAGE_PASS");
$finish;
end
endmodule
The same type can be named as protocol_types::state_t when an explicit
scope is clearer than importing all package names. Avoid broad wildcard
imports from several packages when names may collide. A package is a compiled
SystemVerilog construct, unlike a text include, which is expanded by the
preprocessor.
Save the snippets in protocol_types.sv and state_check.sv, then run:
iverilog -g2012 -Wall -s state_check -o sim/package.vvp protocol_types.sv state_check.sv
vvp sim/package.vvp
Expected output is PACKAGE_PASS. If the selected tool rejects the construct,
record that compatibility result; do not silently switch language modes.
Visual explanation
Connect syntax with simulator behavior
Worked example
Read and run the supplied SystemVerilog source
Example source · Day 21
module day21_types;
logic four_state;
bit two_state;
logic [7:0] packed_data;
logic [7:0] unpacked_data [0:1];
logic [3:0] matrix [0:1][0:1];
typedef logic [7:0] byte_t;
byte_t packet_header;
logic signed [7:0] signed_value;
logic [7:0] unsigned_value;
logic [3:0] truncated;
logic [7:0] corrected;
string label;
initial begin
four_state = 1'bx;
two_state = 1'b0;
if (four_state !== 1'bx || two_state !== 1'b0) $fatal(1,"state types");
four_state = 1'bz;
if (four_state !== 1'bz) $fatal(1,"z state");
packed_data = 8'hA5;
if (packed_data[7:4] !== 4'hA) $fatal(1,"packed");
unpacked_data[0] = 8'h12;
unpacked_data[1] = 8'h34;
if (unpacked_data[1] !== 8'h34) $fatal(1,"unpacked");
matrix[1][0] = 4'hC;
if (matrix[1][0] !== 4'hC) $fatal(1,"matrix");
packet_header = 8'h5A;
if (packet_header !== 8'h5A) $fatal(1,"typedef packet");
signed_value = -8'sd3;
unsigned_value = 8'hFD;
if (!(signed_value < 0) || unsigned_value !== 8'd253) $fatal(1,"signedness");
truncated = 4'(8'hF3);
corrected = 8'(8'hF3);
if (truncated !== 4'h3 || corrected !== 8'hF3) $fatal(1,"casts");
label = "packet";
if (label.len() != 6) $fatal(1,"string");
$display("PASS Day 21: data types and deliberate truncation detected");
$finish;
end
endmodule
Compile and run
mkdir -p sim logsiverilog -g2012 -Wall -o sim/day21.vvp tb/day21_types.svvvp sim/day21.vvp
What to verify
- logic vs bit
- X/Z 4-state
- packed and unpacked arrays
- multidimensional array
- typedef
- signedness
- casts
- strings
- packet fields
- bug fix
Pass condition: PASS is printed and $fatal is never triggered.
Hands-on practice
Complete the exercises in order
- 1
Compare logic and bit initialization and X/Z assignments.
- 2
Measure 2-state versus 4-state behavior using === and !==.
- 3
Create and index packed vectors.
- 4
Create and index unpacked arrays.
- 5
Build a multi-dimensional array and print selected entries.
- 6
Declare typedef aliases for packet fields.
- 7
Compare signed and unsigned values at boundaries.
- 8
Demonstrate explicit casts and width truncation.
- 9
Use strings for human-readable labels.
- 10
Represent packet header fields with typed SV variables.
Written assignment
- Explain bit versus logic and demonstrate X/Z handling.
- Show signed and unsigned interpretations of the same bit pattern.
- Explain packed versus unpacked dimensions with examples.
- Document one deliberate truncation bug, its correction and evidence.
- Convert one Verilog testbench data model into SystemVerilog.
Debug challenge
Find and fix width, signedness and explicit-cast errors in the supplied data model.
Completion criteria
Ten mapped exercises, self-checking PASS, deliberate width bug detected and fixed.
Knowledge check
Check your understanding
Why can logic represent X while bit cannot?
logic is four-state; bit is two-state.
How does logic [7:0] a differ from logic a[0:7]?
The first is a packed vector; the second is an unpacked array.
What happens when a wider unsigned value is assigned to a narrower destination?
High-order bits are truncated.
Why should signedness be explicit in arithmetic checks?
The same bit pattern can represent different signed and unsigned values.
Why is an enum useful for protocol states?
It gives legal values meaningful names and improves type checking and debug.
When is case equality (===) useful in verification code?
When X and Z bits must be compared as explicit values.
Evidence to retain
- source code
- simulator version and compile command
- PASS/FAIL transcript
- before/after debug note