Tutorials

Learn More

Structure in SystemVerilog

A structure can contain different members of different data types. An array contains elements of the same data type. This makes structures different from an array.

Syntax:

struct {
  <Data type> <member 1>;
  <Data type> <member 2>;
  ...;
} <struct_name>;

Significance of typedef in structures

Structure example without typedef

Let’s see an example where the typedef keyword is not used.

module struct_example;
  struct {
    string name;
    bit[31:0] salary;
    integer id;
  } employee;
    
  initial begin
    employee.name = "Alex";
    employee.salary = 'h10000;
    employee.id     = 'd1234;
    $display("employee: %p", employee);
    
    // Accessing individual struct member
    $display("employee: name = %s, salary = 0x%0h, id = %0d", employee.name, employee.salary, employee.id);
  end
endmodule

Output:

employee: '{name:"Alex", salary:'h10000, id:1234}
employee: name = Alex, salary = 0x10000, id = 1234

In the above example, the “employee” struct name is used to store information. Employee behaves reference handle to complete information (includes name, salary, and id of an employee). Individual information also can be accessed. Now, if we want to store another set of information for an employee. The typedef keyword allows creating multiple sets of information with different reference handles.

Syntax using typedef:

typedef struct {
  <Data type> <member 1>;
  <Data type> <member 2>;
  ...;
} <struct_name>;

Structure example with typedef

module struct_example;
  typedef struct {
    string name;
    bit[31:0] salary;
    integer id;
  } employee;
    
  initial begin
    employee e1, e2;
    e1.name = "Alex";
    e1.salary = 'h10000;
    e1.id     = 'd1234;
    $display("employee e1: %p", e1);
    
    e2.name = "Bob";
    e2.salary = 'h20000;
    e2.id     = 'd4321;
    $display("employee e2: %p", e2);
    $display("-------------------------------------------------");
    
    // Accessing individual struct member
    $display("employee e1: name = %s, salary = 0x%0h, id = %0d", e1.name, e1.salary, e1.id);
    $display("employee e2: name = %s, salary = 0x%0h, id = %0d", e2.name, e2.salary, e2.id);
  end
endmodule

Output:

employee e1: '{name:"Alex", salary:'h10000, id:1234}
employee e2: '{name:"Bob", salary:'h20000, id:4321}
-------------------------------------------------
employee e1: name = Alex, salary = 0x10000, id = 1234
employee e2: name = Bob, salary = 0x20000, id = 4321

Types of structures

  1. Packed structures
  2. Unpacked structures

Packed structures

Similar to a packed array, if memory allocated for variables in a structure is contiguous, then it is called a packed structure.

Only packed data types are allowed in packed structures.

Ex. A string is not a packed data type, so code will not compile. To use string as a data type in structure, unpack structures can be used.

The “packed” keyword is used to declare a packed structure.

Packed structure Example
module struct_example;
  typedef struct packed {
    
    bit[31:0] salary;
    integer id;
  } employee;
    
  initial begin
    employee emp1, emp2;
    emp1.salary = 'h10000;
    emp1.id     = 'd1234;
    $display("EMP 1: %p", emp1);
    
    emp2.salary = 'h12000;
    emp2.id     = 'd4321;
    $display("EMP 2: %p", emp2);
  end
endmodule

Output:

EMP 1: '{salary:'h10000, id:1234}
EMP 2: '{salary:'h12000, id:4321}

Unpacked structures

An unpacked structure is not as memory efficient as packed data structures.

By default, a structure is unpacked in nature.

module struct_example;
  typedef struct {
    string name;
    bit[31:0] salary;
    integer id;
  } employee;
    
  initial begin
    employee emp1, emp2;
    emp1.name = "Alex";
    emp1.salary = 'h10000;
    emp1.id     = 'd1234;
    $display("EMP 1: %p", emp1);
    
    emp2.name = "John";
    emp2.salary = 'h12000;
    emp2.id     = 'd4321;
    $display("EMP 2: %p", emp2);
  end
endmodule

Output:

EMP 1: '{name:"Alex", salary:'h10000, id:1234}
EMP 2: '{name:"John", salary:'h12000, id:4321}

Passing a structure in function or task

In the below example, two functions are used for allocating information to structure members and another function to print the structure. Similarly, a structure can be used as an input argument for tasks.

Example:

module struct_example;
  
  typedef struct {
    string name;
    bit[31:0] salary;
    integer id;
  } employee;
    
  function void print_struct(employee emp);
    $display("EMP: %p", emp);
  endfunction
  
  function employee create_struct(string name, bit [31:0] salary, integer id);
    employee emp;
    emp.name = name;
    emp.salary = salary;
    emp.id     = id;
    return emp;
  endfunction
  
  initial begin
    employee emp1, emp2;
    emp1 = create_struct("Alex",'h10000, 'd1234);
    emp2 = create_struct("John",'h12000, 'd4321);
    print_struct(emp1);
    print_struct(emp2);
  end
endmodule

Output:

EMP: '{name:"Alex", salary:'h10000, id:1234}
EMP: '{name:"John", salary:'h12000, id:4321}

Key Points

  1. In a packed structure, if any data type is 4-state, then the complete structure is treated as a 4-state structure.
  2.  The packed structure is by default unsigned in nature. To declare a packed signed structure, the below syntax is used.

Syntax for packed signed structure

typedef struct packed signed {
  <Data type> <member 1>;
  <Data type> <member 2>;
  ...;
} <struct_name>;

Unions in SystemVerilog

Unions are similar to structures that can contain different data types members except they share the same memory location. Hence, it is memory efficient data structure. But it also restricts the user to use one member at a time.

Syntax:

union {
  <Data type> <member 1>;
  <Data type> <member 2>;
  ...;
} <union_name>;

Union Example

module union_example;
  typedef union {
    bit[15:0] salary;
    integer id;
  } employee;
    
  initial begin
    employee emp;
    emp.salary = 'h800;
    $display("salary updated for EMP: %p", emp);
    emp.id     = 'd1234;
    $display("ID updated for EMP: %p", emp); //Note: Salary information will be lost
  end
endmodule

Output:

salary updated for EMP: '{salary:'h800, id:Z}
ID updated for EMP: '{salary:'h0, id:1234}

System Verilog Tutorials