In reply to russ.petersen@broadcom.com:
Hi Russ,
I Tudor introduced me to layered sequencing earlier this year, and I have adopted the technique since. It sounds like you have run into some of the same things I have. I am using to apply TCP/IP on the LocalLink physical interface. My interpretation of the technique is that I create “high level” transactions, for example, an ARP, UDP, IP, etc, and pass that into, say, the IP_2_Eth agent (to it’s sequencer). The next sequencer immediately sees this, and pulls in the IP transaction, and stuffs it into the payload of an ethernet transaction. Next, my physical interface agent (LocalLink in this case), snags the Ethernet transaction, and builds low level LocalLink transactions. Point being, I rarely create Ethernet packets. I start out with the higher level protocols, and stick those into the pipe. Then each section (an agent) of the larger “layering agent” can build the next level of the protocol (and randomizing the new layer). It sounds a little like you are first making an Ethernet transaction, and then trying to stick the IP transaction into that (which is the opposite direction).
About the constraints; if you have constraints that aren’t changing, you can place them in-line in the translation sequences. Some of my translation sequences don’t even randomize the new transaction type. For example, when I create an Ethernet packet after an ARP packet appears in the downstream sequencer,
right_txn.payload=left_txn.pack8(); // assign ARP packet -> Ethernet payload
// configure the Ethernet packet (nothing to randomize)
right_txn.EthType=ARP;
right_txn.sMAC=left_txn.sMAC;
right_txn.dMAC=left_txn.dMAC;
But, going from IGMP to IP (in-line constraint):
array=left_txn.pack8(); // pack transaction
array_len=$size(array); // record the length
// construct a new IP packet
right_txn=ip_transaction::type_id::create("right_txn");
right_txn.payload=array; // assign to payload
right_txn.payload.rand_mode(0); // lock existing payload values
if(!right_txn.randomize() with {
payload.size==array_len; // lock payload array size
IpProt==IGMP;
left_txn.igmp_type==IGMP_QUERY -> dIP==IGMP_MULTICAST_ALL_HOST_IP;
left_txn.igmp_type==IGMP_REPORT -> dIP==left_txn.grp_addr;
left_txn.igmp_type==IGMP_INVALID -> dIP==left_txn.grp_addr;
}) `uvm_fatal(report_id,"right_txn randomize() failed!")
For any constraints that may change, or are not appropriate all the time; in my case, I want to set the destination MAC address of my ethernet packet, I simply extended the Ethernet transaction class, set the constraint, and used the factory to substitute it.