Implementing callback

In reply to verif_learner:

It’s better to add callbacks using composition and not inheritance. This way you can have multiple sets of callbacks active at the same time.

Example:


class packet_generator_callbacks;
  
  pure virtual task pre_drive(packet p);
  pure virtual task post_drive(packet p);

  // ... callbacks for other methods

endclass



class packet_generator;

  local packet_generator_callbacks callbacks[$];

  
  function add_callbacks(packet_generator_callbacks cbs);
    callbacks.push_back(cbs);
  endfunction


  task drive(packet p);
    foreach (callbacks*)
      callbacks[i].pre_drive(p);

    // base code for 'drive'

    foreach (callbacks[i])
      callbacks[i].post_drive(p);
  endtask

 
  // ... other methods

endclass

You might want to have a [i]post_drive(…)* callback that collects coverage after a drive. Someone else might want to write a callback that waits for a certain state before driving the packet. If you would have implemented callbacks using inheritance, you would need multiple inheritance to get this, because you would need a new packet_generator class that extends from packet_generator_with_coverage and packet_generator_that_waits_for_state. Using callback objects you can combine the two easily.