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.
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).
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.
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\_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.