Home > Community > Blogs > Functional Verification > informative tweets on when inheritance
Login with a Cadence account.
Not a member yet?
Create a permanent login account to make interactions with Cadence more conveniennt.

Register | Membership benefits
Get email delivery of the Functional Verification blog (individual posts).


* Required Fields

Recipients email * (separate multiple addresses with commas)

Your name *

Your email *

Message *

Contact Us

* Required Fields
First Name *

Last Name *

Email *

Company / Institution *

Comments: *

Informative Tweets on WHEN Inheritance

Comments(2)Filed under: Functional Verification, OVM, SystemVerilog, e, Specman, OVM e, AOP, OVM SV, when sub-typing, IES-XL, Twitter, tweeting, when inheritance

Earlier today a lively and very instructive thread on the relative virtues of WHEN Inheritance developed on Twitter between @pmarriott (a D&V consultant in Montreal, Canada), @yaron_think_ver (a verification  consultant based in Israel), and @teamspecman.

Because this exchange was very technical -- hence, beneficial to Specmaniacs -- for those of you not yet on Twitter allow us to replicate the thread here, plus address some of the questions / issues raised that we haven't yet responded too (because we must confess, the the 140 character tweet size limit gets a little tiresome after awhile).

By all means we invite @pmarriott, @yaron_think_ver, and YOU to continue the discussion on Twitter by following the three of us and start tweeting youself, or post comment(s) below.


Initial entry by @teamspecman, 5/3 14:00

Q: Can you replicate e's 'when' inheritance in SystemVerilog? A: Not really. TSN's Corey explains in the comments: http://bit.ly/agcymd #EDA


Comment by @pmarriott, 5/3, 14:54

@teamspecman isn't "when" inheritance was only useful for data items? The OVM/sequences+factory+polymorph makes it redundant anyway surely?


@teamspecman (3 tweets in a row), 5/4, 10:22, 10:23, 10:24

Untrue. There R many aspects that can be added to environment objects such as RT @pmarriott isn't "when" inherit only useful for data items?

Part2: Checking, coverage, speed rates, etc. can all be modeled through 'when' inheritance. Plus ...

Part3: Toggling UVC agents from ACTIVE or PASSIVE in an OVM e env is modeled very elegantly using 'when' inheritance


@pmarriott, 10:25

@teamspecman those env objects are static at run time so when inheritance is less useful - can use regular OOP/factory for their morphology

--> new, Team Specman long form response to this tweet:
They are static at run time however, the topology of an environment can change.  Consider the bus speeds to drive at, the bus widths to drive data across, the configuration of the environment, how many channels are active in the environment, how many DUT's are present in some sort of chain configuration, whether or not you are running in 40G vs 10G operation mode, and the list goes on and on.  If all of the above parameters needed to be tested (IP developer situation), using child classes and factories to configure the environment in every possible mode is extremely tedious to do. Why not let the Generation engine do this for you?


@pmarriott, 10:30

@teamspecman setting a status bit through an accessor method will achieve ACTIVE/PASSIVE toggling too. "when" fields R like case statements

--> new, Team Specman long form response:
We're not sure we understand what you mean by "accessory method".  However, we are sure that you could model the ACTIVE/PASSIVE functionality in a number of ways.  It is the beauty of AOP though that allows users to extend objects based on whether they are ACTIVE or PASSIVE.  Consider adding a new debug statement to be printed out at the end of some sort of transfer reception only on the ACTIVE monitor driving input channel 3.  This is easily achieved through the following: extend ACTIVE CHANNEL3 agent_u { //place print code here};


@yaron_think_ver, 10:34

@teamspecman @pmarriott Also, #Specman's WHEN is a cool way to implement multidimensional inheritance. Anything similar in #SystemVerilog?


@pmarriott, 10:47

@yaron_think_ver @teamspecman "when" does not really give multiple inheritance,though you can do some composition using it, that's different

--> new, Team Specman long form response:
Incorrect: multiple inheritance IS something supported in e through its OOP capabilities.  struct b_s like a_s {}; means that b_s will now inherit the properties of a_s.  Similarly c_s can inherit from b_s and so forth.  What is cool about `when` inheritance though is that one can extend objects based on any number of aspects, allowing you hone in on a very specific subtype such as extend has_checks PASSIVE CHANNEL1 USB30 monitor_u { ...}, which is something unique to e.


@yaron_think_ver, 10:53

@pmarriott Correct. If you have subtype A and subtype B, you automatically have subtype "AB". Not sure if this is possible in #SystemVerilog


@yaron_think_ver, 10:56

Can be very useful: define LONG eth_frame, BAD_CRC eth_frame. U can now use these 2 and also LONG BAD eth_frame


@yaron_think_ver, 11:05

It's not unusual to see things like this in #Specman: var fr = LONG VLAN GOOD_CRC HAS_TCP HAS_IP eth_frame ... not kidding! pretty neat :-)


@yaron_think_ver, 11:09

Doing the same in #SystemVerilog is definitely possible but would require a bit of procedural coding (if/case in pack/unpack) wouldn't it?


@pmarriott, 11:27

@yaron_think_ver some of those long "when" composites make for tricky casting, that's for sure. Always looks sexier than the reality of use


Team Specman

(on Twitter: @teamspecman)


By Paul Marriott on May 4, 2010
The "multiple inheritance" example you give is not multiple inheritance - it is a chain of single inheritance. "when" inheritance does not give true multiple-inheritance capabilities (which allow one to inherit properties and methods from several parents).
As for your environment configuration example of the advantages of "when" inheritance - all these capabilities are fully supported by OOP/factory patterns as they are static at run-time. At the end of the day, "when" inheritance is a clever and, I'll happily admit, convenient form of macro substitution. There are other facets of AOP that are far more useful (tweatking constraints, coverage etc.) - but modifying the static portions of an environment is not that special. At the end of the day, the same thing can be accomplished quite easily using the normal OOP factory pattern.
As for your data class example of extending based on specific aspects, all of that can be done in any language that supports if/then/else/case statements - or, more elegantly, with polymorphism. Too many "when" variants can create type-cast ugliness to say the least. Sometimes what appears to be an elegant solution in principal, is not quite so elegant in practice.
Interesting discussion though!

By teamspecman on May 5, 2010
Hi Paul,
After reading your comment on this post, I wondered to myself why I had never encountered a situation where I would have wanted to create an object that inherited from multiple parents.  In fact, in all of my years of using e, there are only a few situations where I have ever needed to inherit from even a single parent class, and these situations were mainly to adhere to a common set of project or company specific base structs.  Why is this?  In e, variations of a base object can easily be modeled using 'when' inheritance; and upon instantiation of the object, you can specify what the subtypes should be, essentially modeling multiple inheritance ... kind of.  I guess because of this flexibility, the need for multiple inheritance does not arise.  
For example, let's say I wanted to model something like an iPad (let’s pick something trendy right now) and I had three previously existing subtypes that represented a Wifi device, a CPU and a keyboard:
struct base_object_s {
   has_wifi: bool;
   has_keyboard: bool;
   has_cpu: bool;
extend has_wifi base_object_s {...};
extend has_keyboard base_object_s {...};
extend has_cpu base_object_s {...};
Each of the above subtypes of the parent have their own properties (fields, methods, events) to represent how that object behaves.  Now, if I wanted to create a new object to represent an iPad, I could do this in a couple of different ways. If I was only looking to make only make use of the Wifi, keyboard, and CPU  features of the iPad, I could simply instantiate a field called iPad, setting the bools appropriately:
iPad: has_keyboard has_wifi has_cpu base_object_s;
The iPad instance above will have all the features of each of the subtypes, since the syntax above automatically sets each of the bools to TRUE.
If I wanted to add new functionality specific to the iPad subtype, I could create a new object type, enabling the Wifi, keyboard, and cpu functionality and add additional iPad specific functionality:
type device_type_t : [iPad];
// Add new field to the base object that could be of type iPad
extend base_object_s {
  device_type: device_type_t ;
  keep iPad_features is only TRUE ; // empty constraint
extend iPad base_object_s {
     has_touchscreen: bool;
  keep iPad_features is only all of {
  // add funky design features here
The above syntax creates a new subtype specific to an iPad, that, by default, has all of the functionality of the Wifi, keyboard and CPU subtypes as well as adding a touchscreen control field and some funky design features.  
Now, the instantiation of an iPad object becomes a little cleaner:
iPad: iPad base_object_s;
Additionally, the above code example makes use of named constraints in e, which can be overwritten if desired to create variations easily.  Let’s say that we wanted to create a low cost model of the iPad that had no touchscreen or wifi capabilities.  This could be easily achieved through the following:
// Add an extra field to indicate whether we are a low cost or
// regular iPad, with regular being the default
extend iPad base_object_s {
  is_low_cost: bool;
  keep soft is_low_cost == FALSE;  //default
extend iPad is_low_cost base_object_s {
  // Here we overwrite the named constraint for this subtype
  // only, removing the wifi and touchscreen
  keep iPad_features is only all of {
     has_wifi == FALSE;
     has_touchscreen == FALSE;
Using named constraints can enable some nifty modeling capabilities when combined with ‘when’ inheritance, but this is a little outside our scope of discussion, so let’s get back on track.
So, ‘when’ inheritance is not really modelling multiple inheritance in the true sense, which is a OOP related feature only supported in select languages (I don’t believe SV is one of them), but the idea behind multiple inheritance is seemingly fulfilled.  I might even say exceeded due to flexibility of instantiating, but I will let others comment on that due to my lack of experience in using multiple inheritance features of other languages.  
Additionally, typical multiple inheritance problems such as multiple parents having the same name for a field are non existent as, at compile time, all fields are within a single parent and a syntax error is flagged to the user if there is a namespace collision.
Regarding modeling static components using ‘when’ inheritance, I think we will have to agree to disagree on the usefulness.  I have found it very useful in my past work, and have seen it used often in both customers code as well as our own VIP.  While almost anything is possible in any language, it all comes down to how much time you want to spend.  OOP/factories allow replacement of all/some instances of objects in the env with child classes, but you still do need to create the child classes to represent the various flavors of functionality and push them into the environment in the build phase.  This can be quite tedious if you have many variations to model.  As both allocation and generation are done in a single phase in e, much of the environment topology can be controlled through constraints, simplifying and reducing the code required to implement the variations in topology.  I do agree with you that other facets of AOP are also very interesting.  (In fact, I have an additional blog entry around this very topic – recall the recent post on coverage extensions as one example:
Regarding data classes, I completely agree with you that this can be modeled in any language that supports if/then/else or case statements, it is just a matter of how much work required to get you there.  I recall years ago hearing stories (perhaps “rumors” might be the better word) of people who modeled their entire verification environment using Perl.  This boggled my mind!  I have also seen firsthand verification environments created using SystemC in which an entire team of engineers were dedicated to maintaining/enhancing only the “scheduler” portion of the code that interfaced with the simulator.  I have also seen advanced coverage collection and analysis capabilities implemented in thousands of lines of Verilog code.  So anything is possible in any language, it is just a matter of how much work you would like to put in vs. get for free from the built-in capabilities of a language.  
In general, the biggest productivity gains are realized through abstraction.  From what I have seen, AOP is the highest level of abstraction to date for languages and fits perfectly into the hardware verification space, hence the reason behind the large productivity gains realized by e users.  Yes, typecasting can be a bit of drag if you need to access a conditionally existing field under a ‘when’ block.  But there are easy ways to deal with this and I would definitely choose this over creating dozens of child classes in OOP to model various flavors of a single item as the latter is not only challenging to create and maintain, it is also a manual process in which users must think of all situations up front in order to create the various child classes.  
The bottom-line: personally I would rather leave it up to the power of automation to create all possible situations randomly, exploring the DUT to the fullest than to miss a DUT bug due to a situation that I had not thought of up front.  
Keep the posts coming everyone!  Great discussion!
Happy bug hunting,

Leave a Comment

E-mail (will not be published)
 I have read and agree to the Terms of use and Community Guidelines.
Community Guidelines
The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.