Share this post

Link to post

Share on other sites

Wow, starting the questions off with a (not entirely unexpected) doozy! ?

Unfortunately there's no single document which states "Here's a full list of everything that changed". This is because a large number of changes were performed by the Accellera UVM WG prior to the IEEE UVM WG spinning up, so there was never a single "central" location wherein everything was tracked. Many of the changes were also "non-functional", ie. the removal of user's guide-esque material and removing the accidental documentation of implementation-specific artifacts.

The best list we've got of functional changes is the bug database where we tracked the changes required to convert the UVM 1.2 reference implementation to UVM 2017 0.9, and that's not really intended for mass consumption. If I were to go through that list and pick "Justin's Top-N":

Accessors- Almost all fields (e.g. printer knobs, etc) have been replaced with set_/get_<field> accessors. Besides for simply being a better coding convention, this allows for greater extensibility.

Opening up the core services- The user now has the ability to insert their own code within the core services of UVM. One common use case for this would be to create a factory debugger, such that all calls to the factory get reported, or a resource pool with a more performant implementation. It's even possible to implement one's own uvm_root, however that has some additional restrictions called out by the LRM. In the past all of these would have required the user to hack inside their own version of the library.

Library initialization- The library no longer mandates that initialization happen during static init. It must happen during time 0, but any time during time 0 is sufficient. This allows the user to leverage #2, but it also allows for new use cases (e.g. "parameterized classes participating in the name-based factory"). There's also new hooks in the library which allow the user to "start and stop with run_test".

Removing the black magic- Anyone brave enough to expand the field macros would know that pre-2017, there was some scary and completely undocumented stuff going on there. This has all been refactored, and just as importantly, documented in 1800.2-2017, such that users can now implement their own macros and/or policies without having to worry about how it would interact with the Accellera library's implementation.

Policy changes- Lots of extensibility changes here. Printer, packer, et. al now derive from a single common source (uvm_policy). They all support arbitrary extensions, similar to TLM2's Generic Payload, allowing for VIP-specific information to be communicated during their processing (e.g. masking fields from a print or compare operation...). Additionally, the printer now has a much more robust mechanism for tracking the structure being printed, making it easy to implement new printers (XML, YAML, JSON, etc.).

Registers- Surprisingly few changes here. The most obvious change is that you can now unlock a model after it's been locked, which allows you to remove/replace/etc registers within the model during runtime. For SoCs which support hotplugging, or are generally re-configurable, this was a huge gap in 1.2 functionality.

At DVCon 2017 & 2018, there were tutorials which covered all of the above and more, with detailed examples. Aside from #1, most of those changes are for advanced use cases, or providers of infrastructure. Day-to-day users shouldn't necessarily see a drastic change.

Looking at the new Accellera implementation specifically, I'd say that the most impactful change is actually in the handling of deprecation. Pre-IEEE, the library would keep code in deprecation for as long as humanly possible so as to limit exposure to backwards incompatibility. Post-IEEE, the library is still using deprecation, but we are limiting ourselves to the previous LRM version. In other words: If something was deprecated as of 1.2, it has been flat out removed in the implementation of 2017. Additionally, the API for enabling deprecated code has been inverted... instead of defaulting to "enable deprecated APIs", the library defaults to "disable deprecated APIs".