Shallow Copy and Deep Copy

In SystemVerilog, copying objects is a common requirement when working with classes and dynamic data structures. However, the distinction between shallow copy and deep copy is critical for correctly handling memory and avoiding unexpected behavior. This article explains the concepts of shallow and deep copies in SystemVerilog, supported by examples for clarity.

In SystemVerilog:

  • Shallow Copy creates a new object in memory but only copies references for dynamically allocated members or nested objects. It doesn’t recursively duplicate their content. In shallow copy only the handles will be copied
  • Deep Copy explicitly duplicates the entire object, including nested objects and dynamic members, ensuring complete independence. Here new object is created and all the class properties including nested class members will be copied to new handle.

Let’s use a class with a nested object to demonstrate shallow and deep copying effectively.

Defining Classes with Nested Objects

Here, we define a Transaction class that contains a nested object Metadata.

class Metadata;
    int checksum;
    function new(int checksum);
        this.checksum = checksum;
    endfunction
endclass

class Transaction;
    int id;
    Metadata meta; // Nested object

    // Constructor
    function new(int id, int checksum);
        this.id = id;
        this.meta = new(checksum);
    endfunction

    // Display method
    function void display();
        $display("Transaction ID: %0d, Metadata Checksum: %0d", id, meta.checksum);
    endfunction
endclass

Shallow Copy Example

In a shallow copy, a new object is created, but the nested object (Metadata) is shared between the original and the copied object. Modifying the nested object through the copied instance also affects the original.

Shallow Copy Implementation

module shallow_copy_example;
    initial begin
        // Create original object
        Transaction t1 = new(1, 123);
        // Perform shallow copy
        Transaction t2 = new(t1.id, t1.meta.checksum);
        t2.meta = t1.meta; // Share reference of the nested object

        // Modify the copied object
        t2.id = 2;
        t2.meta.checksum = 456; // Modify shared nested object

        // Display results
        $display("Shallow Copy Results:");
        t1.display(); // Nested object is modified
        t2.display();
    end
endmodule

Output:

Shallow Copy Results:
Transaction ID: 1, Metadata Checksum: 456
Transaction ID: 2, Metadata Checksum: 456

Explanation:

  • A new Transaction object (t2) is created.
  • The Metadata object is shared between t1 and t2 (same memory).
  • Modifying meta.checksum in t2 affects t1.

Deep Copy Example

In a deep copy, the Metadata object is duplicated, ensuring complete independence between the original and the copied Transaction.

Deep Copy Implementation

Add a copy method to the Transaction class to create a deep copy:

class Transaction;
    int id;
    Metadata meta;

    function new(int id, int checksum);
        this.id = id;
        this.meta = new(checksum);
    endfunction

    // Deep copy method
    function Transaction copy();
        Transaction new_transaction = new(this.id, this.meta.checksum);
        new_transaction.meta = new(this.meta.checksum); // Create a new Metadata object
        return new_transaction;
    endfunction

    function void display();
        $display("Transaction ID: %0d, Metadata Checksum: %0d", id, meta.checksum);
    endfunction
endclass

Using Deep Copy

module deep_copy_example;
    initial begin
        // Create original object
        Transaction t1 = new(1, 123);
        // Perform deep copy
        Transaction t2 = t1.copy();

        // Modify the copied object
        t2.id = 2;
        t2.meta.checksum = 456; // Modify deep-copied nested object

        // Display results
        $display("Deep Copy Results:");
        t1.display(); // Original remains unchanged
        t2.display();
    end
endmodule

Output:

Deep Copy Results:
Transaction ID: 1, Metadata Checksum: 123
Transaction ID: 2, Metadata Checksum: 456

Explanation:

  • The Transaction object (t2) is a completely new object.
  • The Metadata object is also a new instance, independent of the original (t1.meta).
  • Modifications to t2 do not affect t1.

Summary of the Examples

AspectShallow CopyDeep Copy
Object CreationNew object is created.New object is created.
Nested ObjectsShared references to nested objects.New instances of nested objects are created.
Modification EffectChanges to nested objects affect both instances.Changes to one instance do not affect the other.