How to drive data that might contain part of two packets?

Here is what my interface like:
data[127:0];// one cycle 128bits
valid; start; pkt_len[7:0]; ready

Here is what my packet like:
4byte Header plus 1~256 bytes payload, but the number of payload will always be multiple of 4 bytes by adding 1~3 padding.

Now if there is a situation that DUT might handle: a single cycle’s 128bit data may consist of two different packets, and idle packets may inserted between two packets, and the idle pakcet is fixed pattern(32bits), that is to say, one cycle data combination:

integral reqA + part of reqB

partial or integral reqA + idle

part of reqA

all idle packets

how can i write my driver?

In reply to Marina.Miao:

I am planning to do like this: get_next_item(reqA), get the length of packet, and compare it with 128bit, if less than 128bit, then get_next_item(reqB), then process reqA and partial reqB within one cycle, item_done(), but how can I process the left of reqB in next cycle?

In reply to Marina.Miao:

but how can I process the left of reqB in next cycle?

You don’t call item_done() for the second item, until you are done with it.

However, it sounds like you have a PHY layer that doesn’t match 1:1 with your higher level transactions, so you might also consider adding a layer? A low level driver that knows nothing about packets, and a layered agent above that which translates.

http://verificationhorizons.verificationacademy.com/volume-7_issue-3/articles/stream/layering-in-uvm_vh-v7-i3.pdf

If each low level 128bit transaction was a separate sequence_item, that would come with a performance penalty and would be bad if you ever wanted to use an emulator. However, your low level sequence item could model multiple beats using an array. You’d be free to send as many, or as few, beats as you wanted to, in a single item to the low level driver.

In reply to warnerrs:

Thank you, yes, I should modify item_done()with item_done(reqA ) because reqB is not yet done. your suggestion is good, but I can’t get what you mean by saying higher or lower level transactions.

The parameter to item_done(), does not control which item is completed. It is for sending a response to the sequence, which doesn’t sound like applies to your scenario. Let me change tactic here.

Implementing this in the driver will result in a pipelined driver. So do a little searching for pipelined driver patterns. Here’s a relevant article: Driver/Pipelined | Verification Academy

Layering is just something to consider, especially if your 128bit interface underpins other higher level protocols as well. Read up on layered agents if you want to know more. It would make your driver a simple in-order driver, and move the pipelining to the translation sequence.

In reply to warnerrs:

Thank you for your ideas, but the item_done(rsp) is executed after the a single item is completely driven onto the interface, right? why can’t it be an indication of which item is completed?

In reply to Marina.Miao:

When using get_next_item(), in order to merge your first item with a second; you’d need to call get_next_itme() a second time, before calling item_done() for the first item.

When using the driver pattern:

seq_item_port.get_next_item(req);
//...
//drive signals
//...
seq_item_port.item_done();

You must call item_done() before calling get_next_item() again, otherwise you’ll get an error.

In reply to warnerrs:

Thank you, yes I know this, but the difficult point is the one-cycle data combination is not fixed and within one cycle there will not be two headers