0% found this document useful (0 votes)
36 views

Using 20 Classes 20 Factories 20 The 20 and 20 of 20 Verification

This paper discusses the combination of parameterized classes and factories in SystemVerilog, which provides both static and dynamic polymorphism. Parameterized classes employ static polymorphism by allowing types to be specified at compile-time, while factories employ dynamic polymorphism by allowing object creation to be determined at run-time. The paper reviews the origins of these features, discusses their synergies, and provides examples and guidelines for when to use each approach.

Uploaded by

lagrimaz
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views

Using 20 Classes 20 Factories 20 The 20 and 20 of 20 Verification

This paper discusses the combination of parameterized classes and factories in SystemVerilog, which provides both static and dynamic polymorphism. Parameterized classes employ static polymorphism by allowing types to be specified at compile-time, while factories employ dynamic polymorphism by allowing object creation to be determined at run-time. The paper reviews the origins of these features, discusses their synergies, and provides examples and guidelines for when to use each approach.

Uploaded by

lagrimaz
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

DIGITAL INDUSTRIES SOFTWARE

Using parameterized classes


and factories: The yin and yang
of object-oriented verification
Executive summary
This paper reviews the origins of the class-based and parameterized type features in
SystemVerilog, discusses the synergies created by the combination of these features,
andconsiders the advantages and disadvantages of these practices. This paper
introduces the factory pattern, which has been used with parameterized classes as a
proven technique for writing reusable verification class components, and it provides
examples and guidelines for choosing when it is better to specify items statically with
a type parameter versus dynamically with a factory configuration at runtime.

Authors: David Rich and Adam Erickson

siemens.com/software
White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

Contents

Abstract

Introduction

Parameters – the yin

Factories – the yang

Combining the yin with the yang

Conclusion

References

SIEMENS DIGITAL INDUSTRIES SOFTWARE 2


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

Abstract

SystemVerilog is the culmination of the synergies created by the


many design and verification engineers’ combination of these features. We will
experiences with various solutions to compare these to generic programming
the problem of verification. Most practices in other object-oriented
features of the language have histories programming languages such as C++.
with one particular verification We will consider the advantages and
environment or another, each bringing disadvantages of these practices. We
some measurable benefit to will present issues specific to
SystemVerilog. Sometimes, the SystemVerilog, which arise when using
combination of certain features parameterized classes in the context of
produces a benefit that is greater than the complete language; such as name
the sum of the individual benefits. One search resolution, static variable/method
example of such a combination is the declarations, and inheritance.
joining of the class-based, object-
oriented programming paradigm with Finally, this paper will introduce the
the parameterized type system; the factory pattern, which has been used
combination of which creates with parameterized classes as a proven
parameterized classes. Layered on top of technique for writing reusable
this symbiosis is the factory pattern, a verification class components, and it will
creational design pattern used in provide examples along the way. We will
software programming. The type provide guidelines for choosing when it
parameterization employs static is better to specify items statically with a
polymorphism, while the factory type parameter versus dynamically with
employs dynamic polymorphism. This is a factory configuration at runtime, and
the yin and yang of object-oriented we will provide tips for structuring your
programming. class inheritance hierarchy using
parameterized classes.
This paper reviews the origins of the
class-based and parameterized type
features in SystemVerilog and discusses

SIEMENS DIGITAL INDUSTRIES SOFTWARE 3


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

Introduction

The notion that seemingly opposing Origins of generic programming


forces can beneficially transform each with parameters
other has been around for millennia and The concept of generic programming is
is found in all facets of nature and based on the ability to write code for an
human existence. Hardware description algorithm in a particular programming
languages are no exception. HDLs are a language that is independent of certain
delicate balance of declarative/ parameters that will be specified at a
procedural, combinational/sequential, later point. Many languages call these
and strongly/ weakly typed behaviors. parameters generics, hence the term
generic programming. Ada is widely
Two concepts we shall examine are credited with pioneering this style of
static and dynamic typed programming, which is also a precursor
polymorphism. These terms alone of VHDL.[2]
conjure up opposing forces.
SystemVerilog uses them in a variety of The intent of generic programming is to
different contexts, but generally, static facilitate reuse by writing a portion of
implies fixed, either in existence or in code once and invoking or instantiating
size, for an entire simulation, as it many times with different sets of
opposed to dynamic, which implies generic parameters. Verilog has had this
something that can change during the since its inception, with the
simulation. Polymorphism is the ability instantiation of modules using
to manipulate different data types with overridden module parameters. Verilog
a uniform interface – reusability being only allowed the parameterization of
the key benefit. values that might control bit widths or
array sizes, but SystemVerilog adds the
Generic programming is one application full parameterization of all data types,
of static polymorphism, and the factory including class declarations.[3]
design pattern is one application of
dynamic polymorphism.[1]

SIEMENS DIGITAL INDUSTRIES SOFTWARE 4


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

Origins of programming with The intent of the factory pattern is to


factory design patterns decouple classes from the concrete
Design patterns, such as the factory, are objects they instantiate by delegating
proven techniques for structuring code their creation to a separate factory
that is highly reusable and adaptable to object. A concrete object requests from
change. The seminal book, Design the factory a new instance of a given
Patterns,[4] codified a core set of type. The factory may return an object
patterns that were universally present in of the requested type, or it may be
applications that have withstood the configured to return an object that is a
test of time. These patterns have subtype of the requested type. The
become the hallmark of good object- requesting object does not care as long
oriented design. All design patterns, as the returned object is “at least” the
including the factory, take advantage of type it requested. The requesting object
dynamic polymorphism, a fundamental is thus reusable for the objects it
feature of object-oriented programming requests as well as any their subtypes.
(OOP) languages such as SystemVerilog. Furthermore, dynamic polymorphism
allows reconfiguration of the factory so
that it can return different subtypes
throughout simulation.

Parameters – the yin

Parameters, constants, and const explain this it is helpful to understand


What exactly are parameters, and how the phases involved with accomplishing
do they relate to constants? Why is a a simulation.
const variable not the same as a
constant? These questions seem to be Most simulators go through three
an immense source of confusion, even distinct phases: compilation, elaboration
for experienced SystemVerilog users. To and execution. These phases could be

SIEMENS DIGITAL INDUSTRIES SOFTWARE 5


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

accomplished in separate command


steps or automatically combined in a
single step.

Compilation converts a set of human


readable files into a form suitable for
processing in another phase. This phase
also processes included files, conditional A constant is any expression of literals,
text, and text macros into a single parameters, and functions involving
stream of statements called a other constants. The literal numbers 1,
compilation unit. The compiler 2, 3, 5 and 10 are all constants. The
syntactically recognizes each statement macro `THREE is replaced with text
according to the BNF rules, but before any syntax recognition. Its text
generates no useful executable code in also represents a constant for an
this phase. aggregate data type. The 2*2 is a
constant expression of two literal
Elaboration globally resolves all constants. The parameter FOUR is
instantiations, propagating parameter constant. Constant expressions do not
values and types, and connecting ports. contain any variables. Elaboration
It allocates the space for all static design determines the final value of a constant
units and objects. Elaboration resolves expression.
all hierarchical references, so that it can
identify the data types involved in The compilation phase determines that
expressions, and it then generates code middle will be an instantiation of a
to evaluate each expression. design unit with two parameter
overrides and ‘{1,2,3},V connected to its
Execution, or runtime, initializes all ports. The design unit could be a
static objects and spawns all processes module, program block, or interface
where procedural code exists. The that has not been defined yet. This
simulation kernel controls the execution compilation phase does not perform the
of all processes. Now that we have semantic checks necessary to see if it is
defined these phases, let us look at the legal to override those parameters or if
example below and see how the there are two ports to connect.
simulator interprets the various constant
concepts.

SIEMENS DIGITAL INDUSTRIES SOFTWARE 6


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

Later, the compilation phase reads the is connected to the variable V. The
definition of middle: elaboration phase allocates the static,
module middle #(type T, int N=8) fixed-size array variable top.m1.Fix with
(input T Port1, Port2=5); four elements. It computes the data
T Fix[N]; type vector_t to be a 32-bit integral type
typedef bit [0:N*8] vector_t; and creates the static, dynamically sized
vector_t Dyn[]; array variable top.m1.Dyn with no
initial begin elements.
#25 // move away from time 0
run(); Finally, the runtime phase starts by
end propagating the constant ‘{1,2,3} to
task automatic run(); top.m1.Port1 at time 0. At time 5, top.V
const int C = Port2; is assigned to 10 and propagates to
Fix = `{default:Port1}; top.m1.Port2. Task run is called at time
Dyn = new[C]; 25. The call creates the local const
endtask variable C. The only difference between
endmodule a const variable and a normal variable is
that the only allowed assignment to the
The compilation phase recognizes that T const variable is at the point of its
will be a data type, but each instance declaration.
could result in T having a different type.
The size for the fixed array Fix and the In this case, task run has an automatic
width of vector_t must be declared lifetime, which means that each call to
using constant expressions. The size of the task allocates its local variables. The
the dynamic array Dyncan be any initialization of C occurs on each call.
expression because it will be Therefore, a const variable is not really a
constructed at runtime. constant as far as elaboration or
parameterized types are concerned.
During the elaboration phase, an
instance of middle, named m1, is Classes and paramters with the
created with type T overridden by data SystemVerilog type system
type ABC_t and N overridden by a
constant expression computed with Objects and handles
value 4. Port1 is connected to the A SystemVerilog class declaration is a
constant expression ‘{1,2,3}, and Port2 data type that defines an instance of a

SIEMENS DIGITAL INDUSTRIES SOFTWARE 7


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

class object. Just as in the module module test;


previously defined, a class may contain example #(16) e1();
other data types that are defined during example #(32) e2();
elaboration. However, construction of endmodule
class objects occurs at runtime using
only the special function new(). A class Now there are two definitions of class C,
variable can hold a handle to a along with two sets of static variables:
constructed object. For example: test.e1.h1 and test.e2.h1.
SystemVerilog defines the two classes to
module example #(int W = 8)(); be assignment incompatible simply
class C; because they are declared in different
bit [0:W-1] p; scopes, regardless of whether or not
endclass they contain identical declarations. In
C h1; this case, the class property p in
initial config(); test.e1.C is 16 bits wide and is 32 bits
task automatic config(); wide in test.e2.C.
C h2;
h1 = new(); Parameterized classes
h2 = new(); Taking the concepts of Verilog
endtask parameterization a step further,
endmodule SystemVerilog allows classes to have
their own set of parameters that may be
This example contains a class definition overridden when declaring a class
Cin the module example. If there are no variable. A class declared with
other modules, example will become parameters is called a generic class and
the single top-level instance with one is not a true data type until a class
class definition. The module contains a variable with specific parameter
static class variable h1. In the runtime overrides is declared, which is called a
phase, the call to task config constructs specialized class.
an automatic class variable h2, as well
as constructing two new class C objects. class PC #(type T, int N);
If there are multiple instances of a int i;
module example, each instance creates T sub;
a new class definition. bit [0:N-1] m_int;
endclass

SIEMENS DIGITAL INDUSTRIES SOFTWARE 8


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

PC #(C1, 8) h1; monitor #(REQ) req_monitor = new();


PC #(C2, 16) h2; monitor #(RSP) rsp_monitor =new();
PC #(C1, 16/2) h3; …
endclass
At this point, a generic class with class test extends component;
specific parameters becomes a concrete agent #(C1,C2) agent12 = new();
specialized class. The class variables h1 agent #(C1,C3) agent13 = new();
and h2 are handles to two different endclass
specializations of the generic class PC.
The class variable h3 matches the class Assuming C1, C2, and C3 are unique
specialization of h1 and is, therefore, a class definitions, the declaration of test
matching type. creates two specializations of the agent
and driver classes and three
Using containment hierarchy specializations of the monitor class.
Containment is the HAS-A relationship
of OOP, where one class definition Using inheritance hierarchy
instantiates other class variables. A class Inheritance is the IS-A relationship of
definition can use its parameters to OOP, where an extended class inherits
parameterize the contained class all of the properties and methods from
member variables. its base so that they all can be
referenced directly from the extended
A verification environment will typically class. Parameters applied to the
group class components into a extended class may propagate up to the
containment hierarchy as follows. class base class. Using the same driver class
driver #(type REQ,RSP) extends from the example above:
component;
… class my_driver #(type RQST)
endclass extends driver #(RQST,RQST);
class monitor #(type P) extends …
component; endclass
… class test;
endclass my_driver #(C1) d1;
class agent #(type REQ,RSP) extends my_driver #(C2) d2;
component; endclass
driver #(REQ,RSP) my_driver = new();

SIEMENS DIGITAL INDUSTRIES SOFTWARE 9


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

Each specialization of my_driver creates There is no component#(int)::registry


a corresponding specialization of driver. because no one has defined a type or
instantiated a class variable using the
Dealing with static class properties default parameter values.
In a non-parameterized class, declaring
a static class property creates one In order to create a single, static variable
variable for each declaration of a class common to all specializations of a single
that is shared with all constructed generic class, you must move the static
objects of that class. A static class variable declaration into a common,
property in a generic class is not created unparameterized base class:
until the class becomes a concrete
specialization. A simple typedef can class component_base;
create a specialized class. static component_base registry[$];
function new();
class component #(type T=int); registry.push_back(this);
string m_name; endfunction
static component #(T) registry[$]; endclass
function new(string name); class component #(type T) extends
m_name = name; component_base;
registry.push_back(this); string m_name;
endfunction function new(string name);
endclass super.new();
m_name = name;
typedef component #(C1) endfunction
C1_component_t; endclass
component #(C2) C2_component;
component #(C3) C3_component; Type compatibility issues
A common mistake in casting
The above example creates three static parameterized classes is that class
variables, all queues: inheritance of a parameter does not
component_t#(C1)::registry imply inheritance of the class it is
component_t#(C2)::registry specializing.
component_t#C3)::registry.

SIEMENS DIGITAL INDUSTRIES SOFTWARE 10


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

class Base; Base p;


endclass SubType c = new;
class SubType extends Base; p = c; // legal
endclass
class PC #(type T); Each unique set of parameters applied
endclass to a parameterized class creates a
PC #(Base) P; unique class type. Because Base and
PC #(SubType) C = new; SubType are different classes, the two
P = C; // illegal specializations of PC are not assignment
compatible.

Factories – the yang

The non-virtual constructor problem end


A typical task in transaction-level endtask
verification is to define a transaction endclass
class and a set of components that
operate on that type, such as a stimulus The problem lies with our direct use of
generator and driver. the ApbTrans class’s new method,
commonly called its constructor. The
Here is a naïve attempt at creating a constructor is specific to the class in
driver for a particular transaction type. which it is defined, so any class that
directly calls another’s constructor is
class ApbTrans; ... endclass hard-coded to that specific class. We
class ApbDriver; cannot employ dynamic polymorphism,
task run(); because we cannot substitute the type
forever begin created with a subtype without
ApbTrans trans = new;↓ no reuse modifying the creating class. We are
trans.randomize(); stuck with ApbTrans.
... execute transaction

SIEMENS DIGITAL INDUSTRIES SOFTWARE 11


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

To inject a different type of stimulus, able to create deep compositional


typically a subtype of ApbTrans, we hierarchies of objects, each of which are
would have to write a new driver class. polymorphically substitutable with any
As bad as this sounds, the problem runs of their subtypes. We can substitute the
deeper: the driver can sit at the bottom transaction types a driver operates on,
of a deep hierarchical composition of and we can substitute the driver itself,
objects in the testbench. Changing the as long as these objects delegate
class type requires changing the class instantiation to a factory.
type of its containing parent, and so on
all the way to the top-level container. Employing the factory pattern involves
When we want to make another similar the following.
change, we must fork yet another
branch of class definitions. In such • Define an abstract virtual class that
environments, seemingly small changes defines a method for creating objects,
require large-scale modifications and for example:
class explosion.
virtual class Object;
Ideally, we want to design our testbench pure virtual function Object create();
hierarchy once, yet during construction endclass
we want the ability to modify the types
and number of objects that make up • Define a factory class that can produce
that hierarchy. That is what the factory any subtype of object:
pattern does for us.
class Factory;
The basic factory pattern in Object obj;
SystemVerilog virtual function Object create();
The factory pattern allows polymorphic // delegate creation to subtype itself
substitution by delegating object create = obj.create();
creation to a separate factory object. endfunction
Rather than call new directly, the endclass
instantiating class calls a method, for
example create, of the factory object to Factory factory = new;
get a new instance. By decoupling
instantiating classes from the actual
concrete types they instantiate, we are

SIEMENS DIGITAL INDUSTRIES SOFTWARE 12


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

A typical factory implementation return trans;


employs the Singleton pattern,[4] which endfunction
ensures only one instance is present in endclass
the testbench. We will employ this
pattern in a later example, but for now, You can define any number of subtypes
we simply declare a global instance of you want. The important thing is that
our factory. they all extend from Object. With the
above in place, we can now begin to
• Define concrete subtypes to Object design our classes to use the factory
that implement create: instead of calling new.

class ApbTrans extends Object; class ApbDriver;


typedef enum {WRITE,READ} cmd_e; task run();
rand int unsigned addr; forever begin
rand int unsigned data; ApbTrans trans;
rand cmd_e cmd; $cast(trans,factory.create());
virtual function Object create(); trans.randomize();
ApbTrans trans = new(); ... execute transaction
return trans; end
endfunction endtask
endclass endclass

class ApbWriteTrans extends ApbTrans; The factory returns the subtype instance
constraint write_only { cmd == WRITE; } in a handle to the super class, Object, so
virtual function Object create(); ApbDriver must cast it back into the
ApbWriteTrans trans = new(); particular subtype it expects. Before we
return trans; can use the factory, it must be initialized
endfunction externally with a particular instance of
endclass the subtype we want it to produce. This
is because the factory class is designed
class ApbReadTrans extends ApbTrans; to produce objects of type Object, which
constraint read_only { cmd == READ; } is an abstract virtual type that cannot be
virtual function Object create(); allocated directly. We can only allocate
ApbReadTrans trans = new(); concrete subtypes of Object. The
following code configures the factory to

SIEMENS DIGITAL INDUSTRIES SOFTWARE 13


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

produce different subtypes of Object subtype object is then returned back to


over time. The driver, running the caller as a handle of type Object.
concurrently, will receive objects of The driver then casts this handle back to
whatever type the factory is configured the concrete subtype that it expects.
with at the time it calls factory.create().
The factory pattern solves our original
initial begin problem by delegating the task of
// create driver creation to a factory and, ultimately to
ApbDriver driver = new; the subtypes themselves. This does not
// initialize factory to produce ApbTrans come without costs:
ApbTrans trans = new; // reads/writes
ApbWriteTrans w_trans = new; // writes 1. The factory needs an instance of
only the type it produces as it calls
ApbReadTrans r_trans = new; // reads the non-static, virtual create
only method. This can be an
// start the driver expensive overhead, especially if
fork driver.run(); join_none a general factory mechanism is
employed to produce any type in
// plug in different objects to produce the system.
// over time. Driver unaware, and
unmodified 2. The created objects require a
factory.obj = trans; common class that implements a
#1000; virtual method for construction.
factory.obj = w_trans; This constructor has a fixed
#1000; prototype, which fixes the
factory.obj = r_trans; number and type of arguments
#1000; available to construct an object.
$finish;
end 3. The caller to the factory must
cast its return value to get the
The factory’s obj property is assigned a concrete type. That is a red flag,
particular concrete subtype. The calling as it opens the possibility that
class (ApbDriver) calls the factory’s the type returned is not
create method, which delegates compatible with the type
creation to this subtype. The new expected. The factory could have

SIEMENS DIGITAL INDUSTRIES SOFTWARE 14


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

been initialized with PciTrans, instance of an object can be satisfied


which may extend Object to while deferring the costs of creating the
meet the factory requirements actual object until it is requested.
yet not meet the ApbDriver’s
requirement for an ApbTransor class ObjProxy #(type OBJ=int) extends
subtype. In such cases, you get a Object;
highly undesirable, fatal run- virtual function Object create();
time error. If there is both a OBJ subtype = new;
PciDriver and ApbDriver in the return subtype;
system, how can they possibly endfunction
use the same factory instance endclass
when a factory can only be
configured with one particular The proxy’s create method does not
subtype? create itself – it creates the object it is a
proxy to directly, using new. This
The first problem is solved using the removes the requirement that the
proxy pattern. The second and third created object itself implements the
problems are solved using a create method. Now when we configure
parameterized factory – the Yin of the factory, we plug in an instance of
object-oriented verification. the proxy to a subtype:

Lightweight object proxies ObjProxy #(ApbWriteTrans) w_proxy =


A proxy is a lightweight substitute for new;
the object it represents. With the proxy, factory.obj = w_proxy; // writes only
the factory’s requirement for an

SIEMENS DIGITAL INDUSTRIES SOFTWARE 15


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

Combining the yin with the yang

Dynamic casting with $cast opens the if (factory == null)


possibility for fatal run-time errors. That factory = new;
is bad programming practice; thankfully, return factory;
it is avoidable. endfunction

So how do we design a single factory // Configure which subtype to produce


class that can produce any object static function void set_object(Object
deriving from Object, yet avoid $castand obj);
possible run-time errors for components Factory #(BASE) f = get();
that want only ApbTrans and its f.obj = obj;
subtypes? endfunction
static function BASE create();
We solve the problem by making the Factory #(BASE) f = get();
factory a parameterized class, where the $cast(create,f.create_obj());
parameter specifies the subtype family. endfunction
endclass
class Factory #(type BASE=int);
Object obj; In the factory definition above, we have
virtual function Object create_obj(); applied the Singleton pattern, which has
create_obj = obj.create(); any factory specialization spring into
create_obj.randomize(); existence upon first use. Subsequent
endfunction uses simply return the same instance.
This makes sure we have only a single
// Make sure only 1 instance per sim instance for any given factory
local static Factory #(BASE) factory; specialization.
protected function new(); endfunction
static function Factory #(BASE) get(); We have also provided a static create
method that gets the Singleton instance
of itself and calls the internal create
method. It performs the $cast for us,

SIEMENS DIGITAL INDUSTRIES SOFTWARE 16


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

but because the factory and its obj different types. What if we had a
property are both parametrically typed PciDriver and an ApbDriver making
using the same BASE type, the $cast is requests at random times? How would
guaranteed not to fail. you coordinate the factory’s
configuration to produce the correct
When we write our drivers now, we subtype when you cannot know the
have them make requests to the factory caller at any given time?
specialization that is matched to the
base types we want created. We avoid The parameterized factory allows for a
the $cast, and all type errors are caught separate specialized factory for each
during compilation. type being requested, and we avoid
having to create instances of each
class ApbDrv #(type BASE=ApbTrans); specialized factory ourselves. A call to
task run(); the specialized factory’s static set_object
forever begin or create methods cues its allocation on
BASE trans; demand.
trans = Factory #(BASE)::create();
trans.randomize(); Here’s our new top level, which is highly
... execute transaction reconfigurable and reusable. We have
end added a PciDrv component, defined in
endtask the same fashion as ApbDrv.
endclass
// Create drivers that operate on base
Our original factory implementation types
used a global, non-parameterized ApbDrv #(ApbTrans) apb_drv = new;
factory that would presumably be used PciDrv #(PciTrans) pci_drv = new;
by all components making requests for

SIEMENS DIGITAL INDUSTRIES SOFTWARE 17


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

Conclusion

We have explored the static and within a single environment. All of this
dynamic aspects of type polymorphism has led to improved code reusability by
in SystemVerilog as well as explained reducing the code required for each
the synergies in combining the two specialization.

SIEMENS DIGITAL INDUSTRIES SOFTWARE 18


White Paper – Using parameterized classes and factories: The yin and yang of object-oriented verification

References

1. Steve McConnell, Code Complete: A Practical Handbook of Software Construction 2nd


Edition. Microsoft Press, Redmond, Wa. June 2004.

2. “Generic programming.” Wikipedia, The Free Encyclopedia. 9 Jan 2009,


<http://en.wikipedia.org/w/index. php?title=Generic_programming&oldid=262940482>.

3. “IEEE Standard for SystemVerilog- Unified Hardware Design, Specification, and Verification
Language,” IEEE Std 1800-2005, 2005.

4. E. Gamma, R.Helm, R. Johnson, J. Vlissides, Design Patterns, Elements of Reusable Object-


Oriented Software. Addison-Wesley Publishing Company, Reading Massachusetts, 1995.

5. “Open Verification Methodology User Guide - Version 2.0.1, Octob er 2008”, Mentor
Graphics, Corp and Cadence Design Systems, Inc.

SIEMENS DIGITAL INDUSTRIES SOFTWARE 19


Siemens Digital Industries Software About us

Offices Siemens Digital Industries Software helps


organizations of all sizes digitally transform using
Headquarters
software, hardware and services from the Siemens
Granite Park One 5800 Granite
Xcelerator business platform. Siemens' software and the
Parkway
comprehensive digital twin enable companies to
Suite 600
optimize their design, engineering and manufacturing
Plano, TX 75024 USA
processes to turn today's ideas into the sustainable
+1 972 987 3000
products of the future. From chips to entire systems,
Americas from product to process, across all industries. Siemens
Granite Park One 5800 Granite Digital Industries Software – Accelerating
Parkway transformation.
Suite 600
Plano, TX 75024 USA David Rich
+1 314 264 8499 Adam Erickson

Europe
Stephenson House
Sir William Siemens Square Frimley,
Camberley
Surrey, GU16 8QD
+44 (0) 1276 413200

Asia-Pacific
Unit 901-902, 9/F
Tower B, Manulife Financial Centre
223-231 Wai Yip Street, Kwun Tong
Kowloon, Hong Kong
+852 2230 3333

For additional numbers, click here.

10/2023 81184-C2

You might also like