Logic Design - Classes in SystemVerilog (part 3)

avatar

[Edit of Image1]

Introduction

Hey it's a me again @drifter1!

Today we continue with the Logic Design series on SystemVerilog in order to cover more about Classes. This is part 3 and also the final part! I highly suggest checking out part 1 and part 2 before getting into this one.

So, without further ado, let's get straight into it!


Classes (...)

Parameterized Classes

SystemVerilog's parameter system can of course also be used with Classes. Using it it's thus possible to write so called Generic Classes, where each instantiation can specify different data types, array sizes etc. So, through parameterization a single class can be used for the creation of different objects.

Parameters are added in-between #() after the class name, both in the declaration of the class and the instantiation of the object.

class className #(<parameter_list>);
    ...
endclass

className #(<parameter_list>) instance;

For example, let's suppose that we add an integer parameter of the name size, which specifies the bit length of some data or address bus, and has a default value of 32 bits. An object can override that value with 16 quite easily, as shown below.

class className #(int size = 32);
    ...
endclass

className #(.size(16)) instance;

Overriding a type is also quite easy. A type parameter has to be specified that can then be overridden in the same way as any other parameter.

class className #(type T = real);
    ...
endclass

className #(.T(int)) instance;

Of course, any type can be passed as the parameter, even user-defined classes, structs, arrays etc.

Out-of-Block Method Declaration

Because Classes can easily become quite long, SystemVerilog allows the definition of methods to exist outside of the class block. The extern keyword has to be added in front of such methods.

extern function funcName();
extern task taskName();

Of course, the method implementations can also exist in completely different files. In that case, the include compiler directive has to be used so that the header (class definition) is "included" in the corresponding implementation file.

If the class definition is located in file "className.sv" and the class is called className, the corresponding out-of-block declaration would have to be of the sort:

`include "className.sv"

function className::funcName();
    ...
endfunction

task className::taskName();
    ...
endtask

In the "main" module only this final file will have to be included.

Data Accessibility

Be default, any class member is accessible from outside the class. If some members (properties or methods) shouldn't be assessible they have to be marked as local. Even classes that extend the class can't access such members. If local members should be accessible by subclasses, the protected keyword has to be used instead.

For example:

class className;
    int p1;
    local int p2;
    protected int p3;
endclass

In this class:

  • p1 is accessible from anywhere
  • p2 only within the class
  • p3 from within the class and any subclass that extends this class

Abstract (Virtual) Classes

Last time, we showed that methods can be marked as virtual, which allows for different implementations in the subclasses that inherit from that base class.

Additionally, SystemVerilog also allows for the creation of Virtual Classes marked by the virtual keyword. Such Classes contain only virtual methods, that provide the prototype that the extending classes need to follow exactly when overriding them.

The implementation can also be left completely blank in the virtual method by adding the pure keyword.


RESOURCES:

References

  1. https://www.chipverify.com/systemverilog/systemverilog-tutorial
  2. https://www.asic-world.com/systemverilog/tutorial.html

Images

  1. https://www.flickr.com/photos/creative_stock/5227842611

Block diagrams and other visualizations were made using draw.io


Previous articles of the series

Verilog

SystemVerilog

  • From Verilog To SystemVerilog → Data Types, Arrays, Structures, Operators and Expressions
  • Control Flow → Additional Procedural Blocks, Loops, Conditional Statements, Functions and Task Features
  • Processes → Fork - Join in Verilog and SystemVerilog, Process Control (wait fork, disable fork)
  • Events → Interprocess Communication, Events (Definition, Triggering, Waiting, Sequencing, Merging, as Arguments)
  • Semaphores and Mailboxes → Semaphores (Creation, Methods), Mailboxes (Definition, Methods)
  • Interfaces (part 1) → Interfaces (Definition, Port and Signal Lists, Instantiation), Modports
  • Interfaces (part 2) → Parameters, Tasks and Functions (Importing, Exporting), Clocking Blocks (Input and Output Skews)
  • Classes (part 1) → Classes (Definition, Constructor Function, Creating Objects, Accessing Class Members, Static and Constant Class Members, Arrays)
  • Classes (part 2) → Copying Objects (Shallow and Deep Copy), Inheritance, Polymorphism, Virtual Methods

Final words | Next up

And this is actually it for today's post!

I'm not too sure about the next one. Maybe we will make a small post about the program block. Either way, there are still many enormous topics to discuss...

See Ya!

Keep on drifting!

Posted with STEMGeeks



0
0
0.000
0 comments