Sie sind auf Seite 1von 3

software

ENhaNciNg systEm VErilog With aoP coNcEPt


mimic aoP-like functionality using ooP techniques in system Verilog

Nishith shukla

spect-oriented programming (AOP) is a well-established technique for adding, modifying or enhancing functionality to a class or environment. It has become de-facto standard for developing reusable verification environment or component. This article explains semantics differences between AOP and objectoriented programming (OOP) and, where relevant, presents how similar functionality can be obtained using System Verilog.

easiest way to understand this concept is to take a packet written in e and then see how it would be written in System Verilog: Sample e code:
< type packetType : [DBTRANS]; struct TransBaseT { isFirstTrans kind : bool; : packetType;

class TransBaseT; rand bool isFirstTrans; constraint C1 { isFirstTrans == false; } virtual function processTrans(); endfunction virtual function printMe(); endfunction endclass class DbTransT extends TransBaseT;

keep isFirstTrans == false; processTrans() is { } print_me() is { message(LOW,-----------------); message(LOW,Packet Infomration) message(LOW,-----------------); } } > < extend DBTRANS TransBaseT { %addr %data %wr_rd : uint(bits:32); : uint(bits:32); : bool; endfunction virtual function processTrans(); $display(Processing DbTransT Packet) printMe(); endfunction endclass rand bit [31:0] addr; rand bit [31:0] data[]; rand bool wr_rd; [32h0:32hffff] ; data.size() inside [32h0:32hff] } constraint C3 { wr_rd dist { 50 : true, 50 : false } virtual function printMe(); $display(DbTransT : Addr= %h Data = %h Wr_Rd=%h, addr,data,wr_rd); constraint C2 { addr inside

Fundamentals
Despite having many commonalities, e and System Verilog programming languages differ significantly in certain critical areas. For instance, e supports AOP techniques, while System Verilog supports OOP techniques. AOP is popular because its very easy to maintain the scattered code. Programmers can easily express cross-cutting concerns in standalone modules called Aspect. OOP doesnt allow you to decompose a problem into all of its concerns. You can only encapsulate some of the concerns. It really doesnt allow you to deal with cross-cutting concerns. Making OOP do something which it doesnt naturally do, needs some extra efforts and thinking. Its understandable that the ultimate difference between AOP and OOP comes down to organisation of the code. In AOP the code is organised by functionality, while in OOP the code is organised by classes and objects. The
8 6 M ay 2 0 0 9 e l e c t ro n i c s f o r yo u

keep addr in [0x0000..0xffff]; keep wr_rd = select { 50: true, 50: false } print_me() is also { message(LOW,Addr= ,addr, Data=, data,WR_RD=,wr_rd); } processTrans() is only { message(LOW,Processing Databus Transaction); print_me(); } } >

Equivalent System Verilog code:

In classic OOP, you should instantiate the extended class not the base class. If you extend a class, the base class and classes which have already been instantiated will not see changes. Nor would you want them to because the risk is very high that one would carelessly extend a class and corrupt the functionality of all instantiated classes.
w w w. e f y M ag . co M

software
Through abstract factory patterns, OOP offers the option to have extended class correctly modify the functionality of the base class and previously instantiated classes. In e, you can extend the class without changing the name and that changes every instantiation globally. In System Verilog, you can use factory patterns. The sample code for factory patterns in System Verilog is:
class IdbTransT extends DbTransT; rand bit [31:0] channelEnables; rand bool rand bit [3:0] isMySpace; spcEnable; < extend DBTRANS TransBaseT { when SMALL TransBaseT { keep data.size() in [0..10]; } } >

Polymorphism in system Verilog


Like e, System Verilog classes are not automatically constructed and therefore do not use memory before these are explicitly constructed by calling new:
TransBaseT obj_TransBaseT = new; // Handle to instance of Base Class DbTransT obj_DbReqT = new; //Handle to instance of Derived Class obj_TransBaseT.processTrans(); // Calls the base class method with the // constraints in base class obj_DbReqT.processTrans();// Calls the derived class method with the // constraints in derived class

The equivalent code in System Verilog would be:


class LargeDbTransT exteds DbTransT; constraint c5 { data.size() inside [32h50:32h100] } function processTrans(); printMe(); endfunction endclass

constraint C2 { addr inside [32h000f:32hf000]} constraint C4 { channelEnables inside [32h1:32hff] } function printMe(); $display(DbTransT : Addr= %h Data = %h Wr_Rd=%h ChEn = %h isMySpc = %h SpcEn = %h, addr,data,wr_rd,channel Enables,isMySpace,spcEnables); endfunction function processTrans(); $display(Processing IdbTransT Packet) printMe(); endfunction endclass class StimGenT # (type PACKET = TransBaseT); task run; PACKET pkt; for (int i=0;i<5;i++) begin pkt = new; assert(pkt.randomize()); pkt.processTrans(); end endtaks : run endclass : StimGenT module top; StimGenT #(TransBaseT) obj1 = new; stim_gen #(IdbTransT) obj2 = new; initial begin obj1.run; obj2.run; end endmodule : top

Even though one is calling the function from base class, it has a handle to derived class. This is known as polymorphism. OOP users use polymorphism to create factory patterns that mimic AOP functionality of e. In System Verilog, a method called using polymorphism must be declared as virtual. The sample code for calling the derived class method from base class object is given below:
obj_TransBaseT = obj_DbReqT;// Assigning handle of derived class to base class obj_TransBaseT.processTrans(); // Will call derived class method

The following code illustrates that based on the random value of PktSize, you get appropriate extended class handle which is assigned to the base class:
typedef enum {SMALL,MEDIUM,LARGE} PktSize; class stim_fact; //Intermediate Class static function TransBaseT create_stim(PktSize ps) ; case (ps) SMALL : begin DbTransT return s; end MEDIUM : begin IdbTransT return s; end LARGE : begin LargeDbTransT return s; end endcase endfunction : create_stim endclass : stim_fact s = new; s = new; s = new;

controlling factory patterns


Lets say you have a new class IdbTransT derived from DbTransT and you want to instantiate IdbTransT throughout design under the following two conditions: 1. You want changes reflected everywhere in design 2. You want DbTransT to be completely replaced functionality-wise with IdbTransT, but you dont want to modify base class DbTransT
w w w. e f y M ag . co M

This functionality can be achieved with the post_randomize( ) function also.

when inheritance in ooP


The sample code for when inheritance in e language is:

is also in ooP
When you want to add more functionality to a function, the is also extension in e is quite handy.
e l e c t ro n i c s f o r yo u M ay 2 0 0 9 8 7

software
In OOP, by inserting virtual, you can decide whether a method can be modified or not. Not only that, the original method still exists whether or not you have modified it, and any changes you make only apply to that particular sub-class. The System Verilog code for is also functionality is:
class DbTransT extends TransBaseT; virtual function processTrans(); //Local functionality goes here endfunction endclass class IdbTransT extends DbTransT; function processTrans(); super.processTrans(); p.processTrans(); //DbTrans Version super.processTrans(); endfunction endclass DbTransT IdbTransT e = new; T1 = new;

function to call.

the bottomline
As discussed in the article, System Verilog allows you to do all the things that AOP doesits simply a matter of understanding it. It provides painless introduction to OOP, allowing you to use as little or much of OOP as you feel comfortable with, so understanding it is not difficult for verification engineers. Comparing AOP with OOP, it is very obvious that the main difference is in organisation of the code. In AOP you organise your code by functionality, while in OOP you organise your code by classes and objects.
The author is a project leader with more than seven years of experience in Chip/ASIC division of eInfochips

TransBaseT p; TransBaseT p2 = new; p2.processTrans(); //Original Version e.processTrans(); //DbTransT Version t1.processTrans();//IDB Version p = e;

//Local functionality goes here

OOP provides the flexibility of keeping the methods in both the base and all extended classes. By using the power of polymorphism, you can choose and pick which

8 8 M ay 2 0 0 9 e l e c t ro n i c s f o r yo u

w w w. e f y M ag . co M