Friday 29 May 2015

Shallow Copy vs Deep Copy in System Verilog

// SHALLOW COPY

// All the variables are copied however objects are not copied, only thier handles are copied.
// i.e. Shallow copy does not copy objects.
// Any nested objects will NOT be duplicated, only the members themselves

class baseA;
  int unsigned j = 5;
endclass : baseA

class B;
  int unsigned i = 1;
  baseA a = new;
endclass : B

class xtndA extends baseA;
  rand int unsigned x;
  constraint cn1 {
    x < 10;
  }
endclass : xtndA

module top();
  xtndA xtnd1;
  baseA base2;
  baseA base3;
  B     b1;
  B     b2;
  int unsigned test1;
  int unsigned test2;

  initial begin
    b1 = new();         // Creates an object of class B
    b2 = new b1;        // Creates a SHALLOW COPY of b1.

                              //Handle 'a' will be copied but not the object it points to.
    //b2 = new() b1;    // Note: () is not allowed after new

    b2.i   = 10;        // i is changed in b2, but not in b1
    b2.a.j = 50;        // Chaged a.j, shared by both b1 and b2

    test1 = b1.i;       // test1 is set to 1 (b1.i has not changed)
    test2 = b1.a.j;     // test2 is set to 50 (a.j has changed)

    xtnd1   = new();    // Creates an object of class xtndA
    xtnd1.x = 3;        // 3 is assigned to x of xtnd1

    base2 = xtnd1;      // base2 refers to the same object as xtnd1
    base3 = new base2;  // Creates a SHALLOW COPY of xtnd1 (base2 refers to xtnd1)
    $display("===========================");
    $display("b2.i=%0d,  b2.a.j=%0d", b2.i,  b2.a.j);
    $display("b1.i=%0d,  b1.a.j=%0d", b1.i,  b1.a.j);
    $display("test1=%0d, test2=%0d",  test1, test2);
    $display("===========================");
  end
endmodule : top


//Output:
// ===========================
// b2.i=10, b2.a.j=50
// b1.i=1,  b1.a.j=50
// test1=1, test2=50
// ===========================



// DEEP COPY (Full copy)

// Everything including nested objects are copied.
// Custom code is typically needed.

class baseA;
  int unsigned j = 5;
  function baseA copy();
    copy = new;
    copy.j = j;
  endfunction : copy

endclass : baseA

class B;
  int unsigned i = 1;
  baseA a = new;
  function B copy();
    copy = new;
    copy.i = i;
    copy.a = a.copy();    // Call copy() of baseA
  endfunction : copy

endclass : B

module top();
  B     b1;
  B     b2;


  initial begin
    b1 = new();         // Creates an object of class B
    b2 = b1.copy();     // Creates a DEEP COPY of b1. Object 'a' is also copied.

    b1.i   = 10;        // i is changed in b1, but not in b2.
    b1.a.j = 50;        // Chaged a.j of b1 only, it is not shared with b2.

    $display("===========================");
    $display("b2.i=%0d,  b2.a.j=%0d", b2.i,  b2.a.j);
    $display("b1.i=%0d,  b1.a.j=%0d", b1.i,  b1.a.j);
    $display("===========================");
  end
endmodule : top


//Output:
// ===========================
// b2.i=1,  b2.a.j=5
// b1.i=10,  b1.a.j=50
// ===========================




1 comment: