OOPS and UVM

Many of the OOPS principles are already taken care very well due to UVM methodology.
As an user of UVM or testbench writer, what principles of OOPS should I keep in mind.
Examples will help.

I remember the following OOPS principles:

  • encapsulate what varies
  • subclasses should be substitutable for base classes
  • classes should be open for extension but closed for modification
  • depend on abstractions and not on concrete classes

In reply to verif_learner:

Going into UVM base class library we would know how each OOP principal is used for different purpose, which I did not try my myself.

An OOP principal I liked is SRP(Single Responsibility Principal) as I’ve seen enough of testbenches where user adds all the responsibility to a single class which is sometimes harder to debug/reuse.

However I would like to know other practices that an user follows when creating testbench either keeping re-usability in mind or for ease of debug!

In reply to MayurKubavat:

In reply to verif_learner:
However I would like to know other practices that an user follows when creating testbench either keeping re-usability in mind or for ease of debug!

Another one in OOPS concept or design pattern is, strategy pattern.
Here is what I have digested after reading design patterns.

If a functional class has to be implemented then cleanly separate out interface and the core function/algorithm. Now, abstract out the interface so that is it not rightly coupled with core function/algorithm. While doing this, think if algorithm A is replaced with algorithm B, would the classes interfacing with this class remain unchanged.

Now, later, if you have to replace Algo A with B then classes interfacing this class should ideally survive. However, if interface was tightly couple with core function, it is almost likely that when Algo A is replaced with Algo B, one would invariably touch the interfacing classes.

As a trivial example, if I want a class to create IP packets, I can have the following API calls:

  1. select type of IP packet
  2. prepare IP header
  3. prepare IP data
  4. optionally corrupt IP packet etc.

But later, if I change IP packet with something else, the changes could be needed in the interfacing classes. So, instad of the above APIs, I now name then as follows

  1. select layer 3 packet type
  2. prepare header
  3. prepare payload
  4. optionally corrupt

Now, the chances of changes in interfacing classes would be minimum if not zero.