I am working on a testbench that requires building layered transactions. I have looked at various tutorials/papers that talks about different techniques (eg layered sequences, layered agents, layered sequencers, etc) of building layered transactions. Some of which seems like an overkill at least for my application. I am considering using parameterized inheritance for layering transactions (example below). I haven’t found any paper that suggests using this technique. So, before I embark on a journey to build these transactions, I am wondering if there are any pitfalls or complications of implementing transactions this way?
class enet_item extends uvm_sequence_item;
`uvm_object_utils(enet_item)
// Enet fields
rand logic [47:0] da;
rand logic [47:0] sa;
rand logic [15:0] type;
...
endclass
**//### ipv4_item**
class ipv4_item #(type T = enet_item) extends T;
`uvm_object_param_utils(ipv4_item#(T))
// IPv4 fields
rand logic [3:0] ver;
rand logic [3:0] ihl;
rand logic [7:0] tos;
....
endclass
//### ipv6_item
class ipv6_item #(type T = enet_item) extends T;
`uvm_object_param_utils(ipv6_item#(T))
// IPv6 fields
rand logic [3:0] ver;
rand logic [7:0] traffic_class;
rand logic [7:0] flow_label;
....
endclass
//### tcp_item
class tcp_item #(type T = ipv4_item) extends T;
`uvm_object_param_utils(tcp_item#(T))
// TCP fields
rand logic [15:0] src_port;
rand logic [15:0] dest_port;
....
endclass
//## Create Specific Transaction Types
typedef ipv4_item#(enet_item) ipv4_txn;
typedef ipv6_item#(enet_item) ipv6_txn;
typedef tcp_item#(**ipv4_txn**) tcp_ipv4_txn;
typedef tcp_item#(**ipv6_txn**) tcp_ipv6_txn;
//### Instantiate and use the transactions
class my_sequence extends uvm_sequence #(enet_item);
`uvm_object_utils(my_sequence)
...
task body();
randcase
1 : begin
tcp_ipv4_txn txn;
txn = tcp_ipv4_txn::type_id::create("txn_ipv4_txn");
txn.randomize() with ...;
start_item(txn);
finish_item(txn);
end
1 : begin
tcp_ipv6_txn txn;
txn = tcp_ipv6_txn::type_id::create("txn_ipv6_txn");
txn.randomize() with ...;
start_item(txn);
finish_item(txn);
end
endtask
endclass