Let's take a walk down memory lane and remember the fun times we had in college. For a few weeks at the end of the semester, though, things had to get serious, because exam season was starting. I wasn't a really big note taker, so I found myself having to loan notes from my friends. While studying, I couldn't well start scribbling on my friends' notes, as that would have made them really mad. The solution was to make copies on which I could then write to my heart's content. This way I could give the originals back to their owners in the same state as I got them.
covariant return types are a -2012 only feature. before that they were illegal. thats why UVM doesn’t utilise them in various functions such as copy().
ps: actually IUS implemented functions return types as covariant in its initial implementation - however we had to drop that in the light of LRM compliance.
Great post, as always!
If I may, though, a couple of comments:
For creation of new instances you use “new”. The UVM recommendation is to use “create” for factory overriding - this would also help you find out faster that you forgot the factory registration.
Just the same as the overloading of the “copy” in the non-uvm classes that you wrote, that is not “good” because SV does not (supposed to) support overloading, also implementing “clone” function to a class that inherits uvm_sequence_item doesn’t seem to be a good idea, as it is an overloading of that function (since the return type is changed), isn’t it so?
I guess you’re talking about ‘clone()’. That’s explicitly what we want. When we’re cloning a class, we want to create an object of exactly that class, otherwise it’s not an identical clone. This is why we use ‘new()’ instead of ‘create()’. There are also cases where you explicitly might not want to do factory registration (virtual classes, for example).
Overloading ‘copy()’ is the right thing to do precisely because SV doesn’t support function overloading. This way the compiler should flag an error when we’re misusing the function. The same goes for ‘clone()’, plus here we have the added benefit that when we restrict the return type we can do away with casting.
there are several places where new language features would be beneficial for the UVM implementation. unfortunately this is a big task and would affect lots of API (so maybe you are right)
there is no overloading in SV. all you get is the ability to redeclare a function in a derived class with the same signature (then it can be virtual), with a different signature (then it can’t be virtual) or since lrm-2012 with the same signature+virtual and only the return type more specialized (a covariant return type). at no point of inheritance you see more than one function with a given name.
uvm_object has clone method, it calls copy as well as do_copy. do_copy is virtual. we can just override do_copy and use already existing clone method in uvm_object. this will be much more simpler.