System Verilog: ref class member - system-verilog

It should be possible to have a reference as a class member, like in C++. However...
covergroup smurf_car_covergroup(ref smurf_transaction tx)
;
covpt_tx_direction_TURN_LEFT :
coverpoint tx.tx_direction {
bins left[] = {[ENUM_C_LEFT_TURN:ENUM_C_LEFT_TURN]
}
;
}
endgroup
class smurf_coverage_container extends
smurf_coverage_object;
ref smurf_transaction m_ref_smurf_transaction ;
function new(string name, ref smurf_transaction) ;
m_ref_smurf_transaction=smurf_transaction ;
super.new(smurf_transaction) ;
// does the following:
// // m_smurf_bicycle_covergroup
//= new(smurf_transaction) ;
// etc
endfunction : new
function void smurf_sample() ;
// important
if (m_ref_smurf_transaction.is_bicycle() )
m_smurf_bicycle_covergroup.sample () ;
if (m_ref_smurf_transaction . is_car () )
m_smurf_car_covergroup .sample () ;
endfunction : smurf_sample
endclass : smurf_coverage_container
This doesn't work because ref isn't allowed to apply to class fields - the compiler complains "Following verilog source has a syntax problem : NNN: token is smurf_transaction."
Clearly holding a reference (so that when another class assigns its handle to a new object, the sampled object is updated automatically) is technically possible, so what syntax would acheive this effect?
Note I can't add arguments to the sample method owing to coding guidelines and common sense.

The ref keyword only applies as connection type to arguments like in a task or function. It is not needed(allowed) in a class variable declaration because a class variable is always a reference to a class object. See my short class on classes.

A ref argument is a variable passed by reference. This type of argument are not a copy but a reference to the original variable(in this case the object of the class).
Arguments passed by reference are not copied into the subroutine area, rather, a reference to the original argument is passed to the subroutine. The subroutine can then access the argument data via the reference.
From section 13.5.2 in [IEEE Std 1800-2012].
Thus using ref for a class variable is not needed .You can directly pass the object of the class .

Related

How to use enum in class (C++)?

enum TokenType{
Eof,
Ws,
Unknow,
//lookahead 1 char
If,Else,
Id,
Int,
//lookahead 2 chars
Eq,Ne,Lt,Le,Gt,Ge,
//lookahead k chars
Real,
Sci
};
class Token{
private:
TokenType token;
string text;
public:
Token(TokenType token,string text):token(token),text(text){};
static Token eof(Eof,"Eof");
};
In this code I want to create a Token Object eof, but when I compile it it tells me that the Eof is not a Type. Why?
When I use TokenType token=TokenType::Eof it works. But when I passed the Eof into the constructor as a parameter, an error occurred. How could I solve it? Is it related to the scope. I try to use TokenType::Eof as the parameter also fail.
The problem is unrelated to the enumeration, the problem is that the compiler thinks you're declaring a function. For inline initialization use either curly braces {} or assignment-like syntax.
However, you can't define instances of a class inside the class itself, because the class isn't actually fully defined yet. It will also leas to a kind of infinite recursion (Token contains a Token object, which contains a Token object, which contains a Token object, ... and so on in infinity).
You can, on the other hand, define pointers to class inside itself, or references, because that doesn't require a fully defined class, only knowledge that the class exists.
So as a workaround perhaps use reference, that you initialize to a variable defined outside the class:
class Token
{
// ...
private:
static Token& eof; // Declare the reference variable
};
And in a source file:
namespace
{
// Define the actual "real" instance of the eof object
Token eof{ Eof, "Eof" };
}
// Define the reference and initialize it
Token& Token::eof = eof;
Look closely. The error messages tells you where exactly your error lies, including a line number. The compiler sees a function prototype, with Eof being the type of the first argument.
Because Eof is not a type, but just one possible value of a type.
It's really not clear what your design intent here is, but you need to make a clear mental difference between the type you've created, TokenType and its different values.

Store reference to array/queue in SystemVerilog

I'd like to store a reference to an array/queue inside a class. It's doesn't seem possible to do this, though.
I'd like to do something like this:
class some_class;
// class member that points to the 'q' supplied as a constructor arg
??? q_ref;
function new(ref int q[$]);
this.q_ref = q;
endfunction
endclass
If q_ref is merely defined as int q_ref[$], then the assignment operator will create a copy, which isn't what I want. I'd like changes in 'q' to be visible inside the class.
Is there some hidden section in the LRM that shows how this can be done?
I'm not looking for the obvious "you have to wrap the array/queue in a class answer", but for something that allows me to interact with code that uses native arrays/queues.
There are only three variable types in SystemVerilog that can store references: class, event, and virtual interfaces variables.
You have to wrap the array/queue as a member in a class object. Then, any method of that class can be used in an event expression. Any change to a member of the class object causes a re-evaluation of that method. See the last paragraph and example in section 9.4.2 Event control of the 1800-2012 LRM.
So, the only solution for you would be to wrap the queue in a class. The latter is always assigned by a reference, as in this example:
class QueueRef #(type T = int);
T queue[$];
function void push_back(T t);
queue.push_back(t);
endfunction // push_back
endclass // Queue
class some_class;
QueueRef q_ref;
function new(QueueRef q);
this.q_ref = q;
endfunction
endclass
program test;
QueueRef q = new;
some_class c = new (q);
initial begin
q.push_back(1);
q.push_back(2);
$display(c.q_ref.queue);
end
endprogram // test

When does Chapel pass by reference and when by constant?

I am looking for examples of Chapel passing by reference. This example works but it seems like bad form since I am "returning" the input. Does this waste memory? Is there an explicit way to operate on a class?
class PowerPuffGirl {
var secretIngredients: [1..0] string;
}
var bubbles = new PowerPuffGirl();
bubbles.secretIngredients.push_back("sugar");
bubbles.secretIngredients.push_back("spice");
bubbles.secretIngredients.push_back("everything nice");
writeln(bubbles.secretIngredients);
proc kickAss(b: PowerPuffGirl) {
b.secretIngredients.push_back("Chemical X");
return b;
}
bubbles = kickAss(bubbles);
writeln(bubbles.secretIngredients);
And it produces the output
sugar spice everything nice
sugar spice everything nice Chemical X
What is the most efficient way to use a function to modify Bubbles?
Whether Chapel passes an argument by reference or not can be controlled by the argument intent. For example, integers normally pass by value but we can pass one by reference:
proc increment(ref x:int) { // 'ref' here is an argument intent
x += 1;
}
var x:int = 5;
increment(x);
writeln(x); // outputs 6
The way that a type passes when you don't specify an argument is known as the default intent. Chapel passes records, domains, and arrays by reference by default; but of these only arrays are modifiable inside the function. ( Records and domains pass by const ref - meaning they are passed by reference but that the function they are passed to cannot modify them. Arrays pass by ref or const ref depending upon what the function does with them - see array default intent ).
Now, to your question specifically, class instances pass by "value" by default, but Chapel considers the "value" of a class instance to be a pointer. That means that instead of allowing a field (say) to be mutated, passing a class instance by ref just means that it could be replaced with a different class instance. There isn't currently a way to say that a class instance's fields should not be modifiable in the function (other than making them to be explicitly immutable data types).
Given all of that, I don't see any inefficiencies with the code sample you provided in the question. In particular, here:
proc kickAss(b: PowerPuffGirl) {
b.secretIngredients.push_back("Chemical X");
return b;
}
the argument accepting b will receive a copy of the pointer to the instance and the return b will return a copy of that pointer. The contents of the instance (in particular the secretIngredients array) will remain stored where it was and won't be copied in the process.
One more thing:
This example works but it seems like bad form since I am "returning" the input.
As I said, this isn't really a problem for class instances or integers. What about an array?
proc identity(A) {
return A;
}
var A:[1..100] int;
writeln(identity(A));
In this example, the return A in identity() actually does cause a copy of the array to be made. That copy wasn't created when passing the array in to identity(), since the array was passed by with a const ref intent. But, since the function returns something "by value" that was a reference, it's necessary to copy it as part of returning. See also arrays return by value by default in the language evolution document.
In any case, if one wants to return an array by reference, it's possible to do so with the ref or const ref return intent, e.g.:
proc refIdentity(ref arg) ref {
return arg;
}
var B:[1..10] int;
writeln(refIdentity(B));
Now there is no copy of the array and everything is just referring to the same B.
Note though that it's currently possible to write programs that return a reference to a variable that no longer exists. The compiler includes some checking in that area but it's not complete. Hopefully improvements in that area are coming soon.

Can you pass by reference in PeopleCode?

I'm new to PeopleCode and as I'm learning functions, I noticed that in PeopleCode, we'd normally pass value using %PATIENT_ID. A friend told me that you can also pass by reference in PeopleCode but how?
PeopleCode passes by reference for functions.
Function addOne(&num As integer)
&num = &num + 1
End-Function;
Local integer &val = 9;
addOne(&val);
MessageBox(0, "", 0, 0,String(&val));
Results in 10
If you are using App Classes it behaves differently
for methods:
Pass by value for simple types (string, int, number,etc)
Pass by reference for objects (rowsets, records, app classes)
Can pass by reference for simple types using the OUT keyword in the parameter list
method addOne(&num as integer out)
Functions which are defined in the same context as the executing code, e.g. page/component/record/field event PeopleCode, always consider parameters as refernces.
Within Application Classes, parameters of simple types on methods can be defined with the 'out' key word to state that they are a references. Methods also automatically pass parameters as references for complex types. Think: "If there is a lot of data, it is a reference"
This documentation will be very helpful for you.
https://docs.oracle.com/cd/E26239_01/pt851h3/eng/psbooks/tpcr/chapter.htm?File=tpcr/htm/tpcr07.htm
Passing Parameters with Object Data Types
Parameters with object data types are always passed by reference:
/* argument passed by reference */
method storeInfo(&f as File);
If you specify the out modifier for a method parameter with an object
data type, it becomes a reference parameter. This means that the
parameter variable is passed by reference instead of the object that
it is pointing at when passed.
For example, if you pass an object parameter with the out modifier:
method myMethod(&arg as MyObjectClass);
Local MyObjectClass &o1 = create MyObjectClass("A");
Local MyOtherObjectClass &o2 = create MyOtherObjectClass();
&o2.myMethod(&o1);
And inside myMethod this occurs:
Method myMethod
&arg = create MyObjectClass("B");
end-method;
Since the method argument is reassigned within the body of myMethod,
&o1 does not point at the new instance of MyObjectClass (initialized
with "B") after the method call completes. This is because &o1 still
references the original instance of MyObjectClass.
However, if &o1 had been passed with the out modifier, after the
method call completes, &o1 points at whatever the parameter was last
assigned to; in this case, the new instance of MyObjectClass. The
parameter, rather than the object, is passed by reference. Using
the Out Specification for a Parameter
In the following example, a class, AddStuff, has a single public
method, DoAdd. This adds two numbers together, then assigns them as
different numbers. In the signature of the method declaration, the
first parameter is not declared with an out statement, while the
second one is.
class AddStuff
​method DoAdd(&P1 as number, &P2 as number out);
​end-class;
method DoAdd
&X = &P1 + &P2;
&P1 = 1;
&P2 = 2;
end-method;
In the following PeopleCode example, an object named &Aref is
instantiated from the class AddStuff. Two parameters, &I and &J are
also defined.
local AddStuff &Aref = Create AddStuff();
local number &I = 10;
local number &J = 20;
The following code example is correct. &J is changed, because of the
outstatement in the method signature, and because the value is being
passed by reference. The value of &I is not updated.
&Aref.DoAdd(&I, &J); /* changes &J but not &I */
The following code example causes a design time error. The second
parameter must be passed by reference, not by value.
&Aref.DoAdd(10, 20); /* error - second argument not variable */

Timer Thread with passed Function* and Param

I'm working on finishing up my server for my first iPhone application, and I want to implement a simple little feature.
I would like to run a function (perhaps method as well), if another function returns a certain value after a certain waiting period. Fairly simple concept.... right?
Here's my basic foundation.
template <typename T,class TYP>
struct funcpar{
T (*function)(TYP);
TYP parameter;
funcpar(T (*func)(TYP),TYP param);
funcpar& operator=(const funcpar& fp);
};
The goal here is to be able to call funcpar::function(funcpar::parameter) to run the stored function and parameter, and not have to worry about anything else...
When I attempted to use a void* parameter instead of the template, I couldn't copy the memory as an object (because I didn't know what the end object was going to be, or the beginning for that matter) and when I tried multiple timers, every single object's parameter would change to the new parameter passed to the new timer... With the previous struct I have a
question:
Is it possible to make an all-inclusive pointer to this type of object inside a method of a class? Can I templatize a method, and not the whole class? Would it work exactly like a function template?
I have a managing class that holds a vector of these "jobs" and takes care of everything fairly well. I just don't know how to use a templatized function with the struct, or how to utilize templates on a single method in a class..
I'm also utilizing this in my custom simple threadpool, and that's working fairly well, and has the same problems...
I have another question:
Can I possibly store a function with a parameter before it's run? Something like toRun = dontrunmeyet(withThisParameter);? Is my struct even necessary?
Am I going about this whole thing incorrectly?
If this is overly ambiguous, I can set you up with my whole code for context
In order to create a class method that takes a template parameter, yes, it would work almost exactly like a function template. For example:
class A
{
public:
template<typename T>
void my_function(const T& value) { }
};
int main()
{
A test;
test.my_function(5);
return 0;
}
Secondly, for your structure, you can actually turn that into a functor-object that by overloading operator(), lets you call the structure as-if it were a function rather than having to actually call the specific function pointer members inside the structure. For instance, your structure could be re-written to look like this:
#include <iostream>
template <class ReturnType, class ParameterType>
class funcpar
{
private:
ReturnType (*function)(ParameterType);
ParameterType parameter;
public:
funcpar(ReturnType (*func)(ParameterType),ParameterType param):
function(func), parameter(param) {}
funcpar& operator=(const funcpar& fp);
//operator() overloaded to be a function that takes no arguments
//and returns type ReturnType
ReturnType operator() ()
{
return function(parameter);
}
};
int sample_func(int value)
{
return value + 1;
}
int main()
{
funcpar<int, int> test_functor(sample_func, 5);
//you can call any instance of funcpar just like a normal function
std::cout << test_functor() << std::endl;
return 0;
}
BTW, you do need the functor object (or your structure, etc.) in order to bind a dynamic parameter to a function before the function is called in C/C++ ... you can't "store" a parameter with an actual function. Binding a parameter to a function is actually called a closure, and in C/C++, creating a closure requires a structure/class or some type of associated data-structure you can use to bind a function with a specific parameter stored in memory that is used only for a specific instance of that function call.