-1

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.

toolic
  • 57,801
  • 17
  • 75
  • 117
user234461
  • 1,133
  • 12
  • 29

2 Answers2

1

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.

dave_59
  • 39,096
  • 3
  • 24
  • 63
  • A class variable is a *handle* to an object - a pointer. The value of the pointer itself is not a reference but an actual piece of storage. In a `task`, time can be passed while an integer `ref` argument to the task is updated in a separate thread. The same principle could and should apply to pointers to objects. So your reasoning is invalid. – user234461 Sep 03 '19 at 10:23
  • Not correct. A class variable can hold a value that represents a handle to an object. It references nothing (null) until someone makes an assignment to that variable. Please see https://stackoverflow.com/questions/31017629/what-does-ref-mean-in-systemverilog/31017968#31017968 – dave_59 Sep 03 '19 at 13:51
  • non sequiter. A handle implies storage. A `ref` does not. – user234461 Sep 04 '19 at 11:26
  • You are correct that a handle implies construction of an object. But the value that gets assigned to a class variable is not the actual image/storage of that object, its just a pointer to where that storage is located. In C++, you would use `smurf_transaction* m_ref_smurf_transaction`, but in SystemVerilog, the `*` is always implied, and there is no form without it implied. – dave_59 Sep 04 '19 at 15:31
1

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 .