Packages, Class Names and UVM

Some time ago I wrote a post that challenged some of the established coding conventions of modern SystemVerilog. In particular, I expressed my displeasure with the fact that all training material from EDA companies, tutorial sites and other learning resources state that packages should always contain a "_pkg" suffix appended to the package name and that all identifiers in the package (class/function/constant names) should contain the package name as a prefix. I attribute this to the significant C legacy that exists in our field, as the C language doesn't have any construct for packaging code.


This is a companion discussion topic for the original entry at https://verificationgentleman.netlify.app/2015/12/06/packages-class-names-and-uvm.html

Awesome! Keep fighting the good fight here :slight_smile:

“all identifiers in the package (class/function/constant names) should contain the package name as a suffix”

Did you mean to say prefix instead of suffix? That’s the pattern that I observed to be mostly used.

I did mean to write prefix. It was a typo that I fixed now.

Our company recommendations are that packages have the suffix _pkg, classes have the suffix _c, and a variety of other suffixes. By keeping the suffixes short, you have less to type (and hence, fewer bugs). So, your example above would be:
`uvm_object_utils(some_pkg::some_c)

Instances within the package don’t need the package scope since it’s implicit. So you would declare them as follows:

some_c some; // maybe ‘some’ isn’t a good example…
drv_c drv; // here is a driver, again following our conventions

And instances outside of the package are required to use the scope resolution operator:

some_pkg::drv_c some_drv;

Forgive the blatant plug here: All of the UVM coding guidelines that we have successfully followed for 4 years now are given in my book, Advanced UVM (Amazon).

Sigh… then someone will just include your newly created class in two different packages. :frowning:

using the fully qualified name to avoid the TPRGED warnings is especially useful when you are using the UVM regmodel very hierarchically, and allowing the same register class names at different levels of hierarchy.

“classes have the suffix _c”
What do you use for constraints?
Does your firm publish their coding guidelines?

The benefits of this style makes sense to me. It’s been quite a few years now, Tudor, are you still coding this way?

I don’t fully understand this downside you are pointing out, hevangel. Would you mind describing this scenario more for me?

Yes, of course.

In regard to combining this style with naming conventions, how are you avoiding class/variable name collisions in your code ie. driver drv; or driver\_c driver; or driver m\_driver;? Why have you chosen the convention you chose? And if you are choosing driver\_c driver; what suffix are you using for constraints?

I prefer driver drv;. If the shortened name is too ugly, I’ll do some\_package::driver driver;. Sometimes it’s also acceptable to shadow the class name and do driver driver;, because you don’t need to use that class inside that scope anymore.

For private fields, I’d go with driver m\_driver; or, since I started writing more Python, driver \_driver;.

Under no circumstances would I put suffixes on class names (driver\_c).

For me this is a tough choice because it is a choice of the least evil.

driver drv; is good except it breaks the software practice of using unabbreviated dictionary words. On the other hand, this type of word shortening is extremely common place in our industry, RTL included.

driver driver; I didn’t know some compilers would allow this. I tried with VCS 2020.03 and it would not compile.

driver m\_driver; This works for keeping private fields from colliding with the class, but is not of help for non-private fields. In addition software practices are against this type of thing. hungarian notation - What does `m_` variable prefix mean? - Stack Overflow

driver\_c driver; The postfix on class names, or on any type for that matter, is in a small way code duplication ie. we put the class key word and _c. However these types of suffixes are all over the place for other types we create in SystemVerilog. hungarian notation - What does `m_` variable prefix mean? - Stack Overflow

I think if our convention was to use capitals in class names like some other languages, Driver driver;, we’d be good to go, but alas we don’t. Since we do use suffixes elsewhere I’m personally leaning toward driver\_c driver;. The nice thing is it works well in all circumstances ie. not just private variables, or when the abbreviated version of the word is still clear.

I’m curious what is behind your strong feeling against driver\_c driver;?

The link you mentioned relates to using ‘m_’ when not needed. In the back of my mind, I was thinking of situations where you get clashes between a function and a private field. Something like a class that has a ‘some_property()’ function and an internal field for the property. The internal field has to be called something other than some\_property, so I usually use ‘_some_property’. (The idea is that obj.some\_property() reads better than obj.get\_some\_property().) If I had a get\_/set\_ pair of functions, I’d also use some\_property for the field, even if it is internal.

driver\_c is basically trading the prefix for a suffix (albeit a shorter one).

I also wanted to mention capitalization of class names in the first reply, but I forgot. I’ve been mulling it for a while now and it’s probably time. If one rejects package prefixes, then it makes sense.

Also, I’m guessing some of the fondness for snake case comes from VHDL, that is case insensitive. Also from C, which prefers snake case, but doesn’t have the issue with types/instances (it has them with structs, but I don’t know whether those were a later addition, after snake case was already established).

Python uses both CamelCase and snake_case, so why not for SV as well?

For me, ‘m_’ is susceptible to having the same issue as unmaintained comments - they can get stale or otherwise be inaccurate giving the reader wrong information. This for sure happens; Have a look at this post from Jeremy who points out incorrect use of ‘m_’ even in UVM source code. https://verificationacademy.com/forums/uvm/guidelines-about-when-use-m-prefix

For method/variable collisions, I like the software practice of making method names verb-like and variables noun-like.

In regards to your statement "driver\_c is basically trading the [package] prefix for a suffix", that is the case, but only when writing code outside of driver\_cs package. If I’m using my\_pkg::driver driver; inside of my_pkg, lets say in my_pkg::agent, it will not compile in at least VCS if not others. That means to be consistent we’d have to differentiate the class name from the variable name. ie. my\_pkg::Driver driver; or my\_pkg::driver\_c driver;, etc (and we can of course drop my_pkg:: within the my_pkg package).

At this moment, I am leaning toward driver\_c over Driver. Though I am a lover of Ruby which also uses CamelCase, driver\_c seems a bit more in line with today’s SV conventions. The only issue I have with it is it collides with my constraint suffix. Bah!

In my courses I recommend a package name as a suffix onto classes and other names to avoid conflicts. “driver_pci” is shorter than “pci_pkg::driver” and very easy to understand. I’ve seen this successfully used on very large projects to avoid name conflicts.

My SV course puts a “_h” suffix on the handle / class variable, but then says, “Follow your company coding guidelines.” The _h is make the examples easier to read, along with _f for fixed size arrays, _d for dynamic, _q for queues, etc. When a student is faced with a block of SV code, these act as reminders to help them grok the inner meaning. Probably not as useful on real projects.