Skip to main content

SystemVerilog Structs, Unions, and Typedefs – User-Defined Data Types Explained

· loading · loading · ·
Hardware Design Verification SystemVerilog Struct Union Typedef Data Modeling RTL Design
Hardware Design Verification
Axolot Logic
Author
Axolot Logic
Digital Design Engineer
Table of Contents
SystemVerilog Design Series - This article is part of a series.
Part 10: This Article

SystemVerilog Structures and User-Defined Types
#

🏗️ What is a Struct?
#

A struct in SystemVerilog is a composite data type that groups different data types into a single logical unit. Similar to structures in C/C++, it allows you to organize related variables under one name.

🔹 Key Features of Structs:
#

  • Heterogeneous data grouping (different types in one structure)
  • Modular data organization
  • Improves code readability
  • Ideal for data packing and protocol modeling

🔹 Basic Struct Syntax:
#

struct {
  data_type1 member1;
  data_type2 member2;
  // ...
} struct_name;

🔹 Example Struct Definition:
#

struct {
  string    name;
  int       age;
  logic[3:0] id;
  bit       is_active;
} employee;

🔹 Packed vs. Unpacked Struct:
#

  • Packed Struct: Bit-accurate, contiguous memory allocation
    struct packed {
      logic [7:0] r;
      logic [7:0] g;
      logic [7:0] b;
    } pixel_t;
    
  • Unpacked Struct: Default, more flexible (members may not be contiguous)

🔹 Accessing Struct Members:
#

employee.name = "Ahmet";
employee.age = 32;
if (employee.is_active) ...

🔹 Using typedef with Structs (Best Practice):
#

typedef struct {
  logic [31:0] addr;
  logic [63:0] data;
  logic        valid;
} transaction_t;

transaction_t trx;

Structs are widely used in SystemVerilog for data packets, protocol messages, and complex data structures in RTL and verification.


🔄 Understanding Unions in SystemVerilog
#

Unions allow a single storage location to be accessed as different data types, providing memory-efficient ways to represent data that can be interpreted in multiple ways.

🔹 Key Features of Unions:
#

  • Shared memory space for all members
  • Only one member active at a time
  • Memory-efficient for alternative data representations
  • Useful for protocol processing and hardware register modeling

🔹 Basic Union Syntax:
#

union {
  data_type1 member1;
  data_type2 member2;
  // ...
} union_name;

🔹 Packed vs Unpacked Unions:
#

  • Packed Union: All members share exact same bit width
    union packed {
      logic [31:0] int_val;
      logic [7:0]  byte_arr[4];
    } data_u;
    
  • Unpacked Union: Members can have different sizes (less common)

🔹 Practical Union Example:
#

typedef union {
  int     as_int;
  shortreal as_float;
  logic [31:0] as_bits;
} number_u;

number_u num;
num.as_float = 3.14;  // Store as float
$display("Integer view: %0d", num.as_int);  // Reinterpret as int

🔹 Union with Struct:
#

typedef struct {
  logic [7:0] addr;
  union {
    logic [31:0] data;
    logic [7:0]  bytes[4];
  } payload;
} packet_t;

🔹 Common Use Cases:
#

  1. Protocol Processing (different interpretations of same bits)
  2. Hardware Register Access (multiple views of same register)
  3. Type Conversion (bit reinterpretation without casting)
  4. Memory Optimization (when only one variant is needed at a time)

🔹 Important Notes:
#

  • Only the last written member should be read
  • No type checking - programmer must track active member
  • Packed unions are synthesizable (unpacked unions typically aren’t)
  • Use with caution in verification due to potential type safety issues

🔹 Union vs Struct Comparison:
#

FeatureUnionStruct
MemoryShared (overlapping)Dedicated (contiguous)
AccessOne member at a timeAll members simultaneously
SizeSize of largest memberSum of all members
Typical UseAlternative representationsData grouping

🏷️ SystemVerilog User-Defined Types and Type Aliases
#

SystemVerilog allows users to define custom data types using the typedef keyword. This feature enhances code readability, reusability, and type abstraction, especially in large RTL or verification projects.


🔤 What is typedef?
#

The typedef keyword creates an alias (alternative name) for an existing data type or a complex type definition.

Basic Syntax:
#

typedef original_type alias_name;

✅ Why Use typedef?
#

  • Improves readability for complex types
  • Simplifies parameter passing in tasks/functions
  • Enables strong typing and abstraction
  • Reduces code duplication

📌 Examples of typedef Usage
#

1. Simple Alias
#

typedef logic [7:0] byte_t;
byte_t a, b;  // Equivalent to: logic [7:0] a, b;

2. Typedef for Structs
#

typedef struct {
  string name;
  int    age;
  bit    is_valid;
} person_t;

person_t user1;
user1.name = "Kerim";

3. Typedef for Enums
#

typedef enum logic [1:0] {
  IDLE,
  RUN,
  DONE
} state_t;

state_t fsm_state;

4. Typedef for Arrays
#

typedef logic [15:0] word_t;
typedef word_t mem_array_t [0:255];  // 256-word memory

mem_array_t my_ram;

5. Typedef for Unions
#

typedef union packed {
  int    as_int;
  byte_t as_bytes[4];
} data_u;

data_u data;

🔁 Using typedef with Parameterized Types
#

You can define flexible and reusable types inside parameterized modules or interfaces:

module fifo #(parameter WIDTH = 8) ();
  typedef logic [WIDTH-1:0] data_t;
  data_t buffer;
endmodule

🧩 Struct Assignment Styles in SystemVerilog
#

SystemVerilog provides flexible methods to assign values to struct elements — both member-wise and aggregate-based.

1. Individual Member Assignment
#

You can assign each member of a struct one by one:

employee.name      = "Ali";
employee.age       = 30;
employee.id        = 4'b1100;
employee.is_active = 1;

2. Aggregate Assignment (Literal Initialization)
#

You can assign the entire struct using a literal list ('{...}), in declaration or at runtime:

employee = '{ "Ayşe", 28, 4'b0011, 1 };

✅ Order must match the declaration order of struct members.

You can also use named assignments for clarity:

employee = '{
  name: "Zeynep",
  age: 25,
  id: 4'b1001,
  is_active: 0
};

🧠 Named assignments make your code self-documenting and less error-prone.

3. Default Value Initialization
#

SystemVerilog allows partial or full default initialization using the default: keyword:

employee = '{logic: 0, default: 0};   // All fields reset to 0 or "", All logic kind variable reset to 0

This is especially useful in testbenches and struct arrays.


🚨 Notes and Best Practices
#

  • Use _t suffix to indicate type aliases (e.g., byte_t, state_t)
  • typedef cannot define a new class—only primitive types, structs, enums, unions, or arrays
  • Highly useful in testbenches, UVM components, and interfaces

📚 Summary Table
#

UsageSyntax ExampleDescription
Alias for basic typetypedef logic [7:0] byte_t;Shorter, reusable name for vector types
Struct aliastypedef struct { ... } my_struct_t;Clean, modular data grouping
Enum aliastypedef enum {A, B, C} mode_t;Finite state or mode definitions
Array aliastypedef logic [15:0] mem_t [0:255];Predefined memory or buffer abstraction
Union aliastypedef union packed { ... } union_t;Bit-shared data representation

SystemVerilog Design Series - This article is part of a series.
Part 10: This Article

Related

SystemVerilog Interface – Modular Signal Grouping with modport and Clocking Blocks
· loading · loading
Hardware Design Verification SystemVerilog Interface Modport Testbench RTL Design Connectivity
Hardware Design Verification
SystemVerilog Loops and Control Flow – for, while, foreach, repeat, break
· loading · loading
Hardware Design Verification SystemVerilog Loops Control Flow Testbench RTL Design Break/Continue
Hardware Design Verification
SystemVerilog Clocking Block – Timing Control for Testbenches
· loading · loading
Verification Hardware Design SystemVerilog Clocking Block RTL Design Testbench UVM Timing
Verification Hardware Design
SystemVerilog Data Types
· loading · loading
Hardware Design Verification SystemVerilog Verilog RTL Design Data Types Synthesis Simulation
Hardware Design Verification
SystemVerilog Enum Data Type
· loading · loading
Hardware Design Verification SystemVerilog Enum FSM RTL Design Testbench Debugging
Hardware Design Verification
SystemVerilog Intoduction
· loading · loading
Hardware Design Verification SystemVerilog Verilog RTL Design UVM Hardware Verification IEEE 1800
Hardware Design Verification