Extending a UVC to implement a higher level protcol

I am relatively new to actually using UVM in a real project, so I am looking for some experienced wisdom.
I want to discuss the merits of extending a UVC or extending the sequences of a UVC / creating a virtual sequence to implement a communication protocol.

Consider a simple interface, it could be I2C or UART or SPI. I have a UVC from my verification library that can drive the that interface at an electrical/pin level and it also takes care of the character (or stream of characters) level allowed by that relevant standard.

Now I have my DUT. My DUT implements a protocol on top of that raw I2C, UART or SPI character stream. For example, old DSL modems had UART interfaces and had an “AT” command set that they understood. A DUT’s I2C interface may implement a register read write protocol where certain characters are interpreted as a “register address” and other characters are the “data to write”. I refer to this as the communication protocol.

I am wondering about the merits of different implementations for the communication protocol.

  1. I could simply write some new sequences for my UVC that know how to assemble the character stream to match my DUT’s communication protocol. They could be API sequences that equate to transactions for my DUT. So for the I2C example I could create an API sequence to write_register(address,data).

  2. I could do that same process with a virtual sequence, which seems to more of less be the same thing unless I want some other control, perhaps synchronizing my communication to other events or signals. This is actually where my current implementation is.

I pretty much understand these two, and have done it successfully (in terms of it works).
So core of my question relates to the merits of option 3.

  1. I think could extend the UVC. I could define a new packet which represented my communication protocol. The new monitor and driver would really amount to assembling / disassembling the character streams and letting the driver / monitor of the base UVC handle it from there. Then my analysis ports and adapters would work at the level of my DUT’s communication protocol - the thing I am really interested in collecting coverage on. So it seems that scoreboards and coverage would be easier to write and may be it would also be easier constrain sequence randomization from above.

I have googled around trying to find an example of this but come up blank.
Is it a common approach? Is it even a good approach or are the actually problems when you come to do it?
If it the right way, then I’d love to see an example.

Thanks for any assistance you can provide

In reply to jason.pearce:

Hi Jason,

I think that you are looking for protocol layering topic (UVM User’s Guide section 6.5.2).
You could also look at this paper: http://verificationhorizons.verificationacademy.com/volume-7_issue-3/articles/stream/layering-in-uvm_vh-v7-i3.pdf

And of course, you can define a higher level of transaction to represent your communication protocol. This approach is commonly used in protocol stack such as Ethernet, USB, PCIe, etc.

An,