How to copy some variables in a base class to a derived class?

Hi,

I have a case where my monitor collects packets in the form of a base class as below:


class pkt_base;
    bit [3:0] data_type;
    bit [31:0] data;
    function new();
    endfunction
endcass: pkt_base

Based on the data_type, I have created two derived classes:


class pkt_A extends pkt_base;
    bit a1;
    bit [15:0] a2;
    function new();
        super.new();
    endfunction

    function unpack();
        a1 = data[0];
        a2 = data[16:1];
    endfunction: unpack
endclass: pkt_A

class pkt_B extends pkt_base;
    bit [3:0] b1;
    function new();
        super.new();
    endfunction

    function unpack();
        b1 = data[3:0];
    endfunction: unpack
endclass: pkt_B

In my model, I want to process these pkt_base objects based on their data_type and create derived packets (pkt_A and pkt_B) from the base packet objects. For example:


    pkt_base packet = new(); // created in my monitor
    ...
    pkt_A pkt_a_o;
    pkt_B pkt_b_o;
    case (packet.data_type)
       PKTA: begin
           pkt_a_o = new();
           pkt_a_o.a1 = packet.data[0];
           pkt_a_o.a2 = packet.data[16:1];
       end 
       PKTB: begin
           pkt_b_o = new();
           pkt_b_o.b1 = packet.data[3:0];
       end
    endcase

This works but I would like to hide the implementation details by using unpack(); methods in my derived packet class. For example:


    pkt_base packet = new(); // created in my monitor
    ...
    pkt_A pkt_a_o;
    pkt_B pkt_b_o;
    case (packet.data_type)
       PKTA: begin
           pkt_a_o = new();
           pkt_a_o.unpack();
       end 
       PKTB: begin
           pkt_b_o = new();
           pkt_b_o.unpack();
       end
    endcase

However, this would be wrong unless I copy packet.data to pkt_a_o.data and pkt_a_b.data first. I was wondering if there’s another way to achieve this? It seems to me that I am missing some important concept of OOP here by copying fields of a base class across to a derived class. Thanks in advance!

In reply to wch:

make unpack take packet as an argument

class pkt_base;
    bit [3:0] data_type;
    bit [31:0] data;
    function new();
    endfunction
    virtual void unpack(pkt_base rhs);
       this.data_type = rhs.data_type;
       this.data      = rhs.data;
    endfunction
endcass: pkt_base

class pkt_A extends pkt_base;
    bit a1;
    bit [15:0] a2;
    function new();
        super.new();
    endfunction
 
    function void unpack(pkt_base rhs);
        super.unpack(rhs);
        a1 = data[0];
        a2 = data[16:1];
    endfunction: unpack
endclass: pkt_A
 
class pkt_B extends pkt_base;
    bit [3:0] b1;
    function new();
        super.new();
    endfunction
 
    function void unpack(pkt_base rhs);
        super.unpack(rhs);
        b1 = data[3:0];
    endfunction: unpack
endclass: pkt_B
pkt_base packet = new(); // created in my monitor
    ...
    pkt_A pkt_a_o;
    pkt_B pkt_b_o;
    case (packet.data_type)
       PKTA: begin
           pkt_a_o = new();
           pkt_a_o.unpack(packet);
       end 
       PKTB: begin
           pkt_b_o = new();
           pkt_b_o.unpack(packet);
       end
    endcase

In reply to dave_59:

Thanks Dave! This is exactly what I was looking for!

In reply to dave_59:

Hi Dave ,

In the packet_base class instead of defining virtual void unpack(pkt_base rhs) ,can’t we
use virtual function void unpack(pkt_base rhs)?

Thanks in advance.