Argument Passing
This article uses the term function in a generic sense. Most of the subject matter in this article also applies to SystemVerilog tasks.
Pass by Value Semantics
The default semantics of function parameter passing in SystemVerilog is pass by value. This applies to all the data types including the container types. The only special case is that of class objects. The objects themselves are not bound to the identifiers. What gets bound to the identifiers is objects' handles (analogous to pointers in C/C++). When a class instance (actually its handle) is passed, the handle itself is passed by value. But since the handle only points to the actual value, the actual object pointed to by the argument passed is same as the object visible inside the function (or task) -- effectively making it seem like pass by reference semantic in case of class objects.
SystemVerilog provides ref keyword which can be used as a prefix with the function arguments. When used, ref ensures that pass by reference semantics is used for argument passing. The ref semantics in SystemVerilog is analogous to use of references in C++.
There are two use cases where using ref for argument passing makes sense. The first use case arises because of the fact that functions can only return one value (leaving aside port like input/output port like argument semantics as available in traditional Verilog). Further tasks can not return even one value. When a function needs to return more than one value or when a task needs to return a value, the pass by reference semantics comes in handy.
The second use case is necessitated by run-time efficiency considerations. When large data values (arrays, queues etc) need to be passed as arguments, the pass by value semantics becomes a lot inefficient. The whole of data would need to be copied every time a function call is made. By prefixing the ref keyword to the argument, one can make sure that no such copying takes place. But this makes the argument itself prone to the danger of getting inadvertently modified by the function's (or task's) code. This danger can be allayed by declaring the ref argument as a constant.
1
2
3
4
5
6
7
| // virtual base class class xactn; // user functions virtual function void pack( ref bytes[]); virtual function void unpack( const ref bytes[]); // other function declarations omitted endclass |
Default Values for Function Arguments
SystemVerilog allows a user to bind default values to a function's arguments. In case no value is specified for an argument for which a default value is available, the default value gets used for the function call. The syntax and semantics used for specifying default values is similar to that of C++:
1
2
3
| task void foo ( int unsigned x, int unsigned y = 10); // the tasks implementation is not provided endtask : foo |
SystemVerilog provides an additional feature though. Unlike C++, SystemVerilog allows a user to use default value for an argument even while supplying custom value for a later argument. The argument for which default value needs to be used is simply given a miss in the argument list during the function call. The later arguments, in case present are provided after pacing another comma (the ,character) after a whitespace to depict missing argument value.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| function void foo( int unsigned first = 1, int unsigned second = 2, int unsigned third = 3, int unsigned fourth = 4); // function's code omitted endfunction : foo // sample possible calls to foo // third and fourth arguments are bound to defaults foo (10, 20); // first and third arguments get default value foo ( ,20, ,40);
|
No comments:
Post a Comment