Uvm_monitor and class parameter

is it common not to have uvm_monitor without parameter?

For example, the following is a snippet from uvm reference guide. The monitor does not have any parameter while driver has user defined sequence_item as a parameter.

class master_monitor extends uvm_monitor;
virtual bus_if xmi; // SystemVerilog virtual interface
bit checks_enable = 1; // Control checking in monitor and interface.
bit coverage_enable = 1; // Control coverage in monitor and interface.
class simple_driver extends uvm_driver #(simple_item);
 simple_item s_item;
 virtual dut_if vif;
 // UVM automation macros for general components
 `uvm_component_utils(simple_driver

Does this mean that I cannot have multiple instances of monitor with different sequence_item types?

In reply to verif_learner:

In your monitor you might use a different seq_item type as in your driver. This gives you some freedom.
You have to declare this variable in your monitor Class.

In reply to chr_sue:

In reply to verif_learner:
In your monitor you might use a different seq_item type as in your driver. This gives you some freedom.
You have to declare this variable in your monitor Class.

I understand what you are saying. My question was that we cannot have 2 instances of the monitor with 2 different type as monitor class hardcodes the transaction class type.

If this is okay in case of monitor class then why do we have parameterized class for driver?

I understand that one can use factory to have different transaction item for different monitor but again I come back to my original question. The same can be done for driver too.

In reply to verif_learner:

You need to learn to look at the UVM source code.
uvm_monitor
is not a parameterized class. It’s just a uvm_component with nothing in it. They (the UVM committee) could have more efficiently used typedef, but they didn’t. They could have made the class parameterized with an analysis_port since almost every monitor has one, but they didn’t.

In reply to dave_59:

In reply to verif_learner:
You need to learn to look at the UVM source code.
uvm_monitor
is not a parameterized class. It’s just a uvm_component with nothing in it. They (the UVM committee) could have more efficiently used typedef, but they didn’t. They could have made the class parameterized with an analysis_port since almost every monitor has one, but they didn’t.

I am not sure what UVM source code is going to tell me additionally when I already know that uvm_monitor does not have any parameter. In fact, my question was the reasoning behind having parameterized class for driver and not for monitor. It’s more to understand the design philosophy rather than to understand what is already there or not there.

Probably, I should post this question in Accelera forum and see what they say.

In reply to verif_learner:

In reply to dave_59:
I am not sure what UVM source code is going to tell me additionally when I already know that uvm_monitor does not have any parameter. In fact, my question was the reasoning behind having parameterized class for driver and not for monitor. It’s more to understand the design philosophy rather than to understand what is already there or not there.
Probably, I should post this question in Accelera forum and see what they say.

See here the source code:

virtual class uvm_monitor extends uvm_component;

  // Function: new
  //
  // Creates and initializes an instance of this class using the normal
  // constructor arguments for <uvm_component>: ~name~ is the name of the
  // instance, and ~parent~ is the handle to the hierarchical parent, if any.

  function new (string name, uvm_component parent);
    super.new(name, parent);
  endfunction

  const static string type_name = "uvm_monitor";

  virtual function string get_type_name ();
    return type_name;
  endfunction

endclass

Don’t consider this as a limitation. In reality it gives you all the freedom you need.

In reply to chr_sue:

In reply to verif_learner:
See here the source code:

virtual class uvm_monitor extends uvm_component;
// Function: new
//
// Creates and initializes an instance of this class using the normal
// constructor arguments for <uvm_component>: ~name~ is the name of the
// instance, and ~parent~ is the handle to the hierarchical parent, if any.
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction
const static string type_name = "uvm_monitor";
virtual function string get_type_name ();
return type_name;
endfunction
endclass

Don’t consider this as a limitation. In reality it gives you all the freedom you need.

what freedom are you talking about?
Can you tell me how I can create 2 instances of the same user defined monitor class. Both these monitors should send different transaction types on its analysis port, apart from using factory method?

I can do what I stating above in case of driver, as I can pass 2 different transaction type class to the 2 instances. Of course, driver will connect to sequencer and not to scoreboard but that’s not the important part here.

In reply to verif_learner:

If you are saying you want to send out 2 different types of transactions, then you do not have 2 monitors of the same type.
I do not know how your UVM database is looking like, because a monitor belongs always to an agent, like the driver and the sequencer. The monitor in your agent1 has a specific transaction and the monitor in your agent2 has another transaction.

In reply to verif_learner:

Here is my understanding:

Usually the monitor is used to collect the transactions from the bus interfaces and do checks and coverage etc. there or send the transactions to analysis components like scoreboards through analysis ports. You have freedom to instance the monitor in an agent or in an sub-system environment component which depends on your test bench architecture. You also have freedom to collect one type transaction or multiple type transactions in one monitor.

If you want to have one monitor which can be reused for multiple instances with different transaction type, maybe you can consider to implement your own parameterized monitor.


 class my_monitor #(type T) extends uvm_monitor;
    T trans;
    ...
 endclass


In reply to chr_sue:

In reply to verif_learner:
If you are saying you want to send out 2 different types of transactions, then you do not have 2 monitors of the same type.
I do not know how your UVM database is looking like, because a monitor belongs always to an agent, like the driver and the sequencer. The monitor in your agent1 has a specific transaction and the monitor in your agent2 has another transaction.

I assumes my question is very simple regarding monitor and driver but apparently it is not.
So, let me back up and explain my problem statement once again.

I have an agent that has driver and monitor class.
I have 2 interfaces in DUT. These interfaces are not two types but same type and 2 instances.
Let us say for example, axi-4

In my environment, i create 2 instances of the agent.
For the first instance of the driver, I pass sequence item type parameter basic_seq.
For the second instance of the driver, I pass sequence item type parameter advance_seq.
Both basic and advance sequence are derived from uvm_sequence_item. Further, advance_seq is derived from basic sequence.

Now, I want to do the same thing for the 2 instances of monitor in the 2 instance of agents.
I want to have one transaction type for the first instance of monitor and something different for the second instance of monitor. I cant do this as monitor class is not typed.
I can only do this using factory, which is ok.

But the fundamental question is, why this difference between driver and monitor?
It is as simple as that.

In reply to Lina.Lin:

In reply to verif_learner:
Here is my understanding:
Usually the monitor is used to collect the transactions from the bus interfaces and do checks and coverage etc. there or send the transactions to analysis components like scoreboards through analysis ports. You have freedom to instance the monitor in an agent or in an sub-system environment component which depends on your test bench architecture. You also have freedom to collect one type transaction or multiple type transactions in one monitor.
If you want to have one monitor which can be reused for multiple instances with different transaction type, maybe you can consider to implement your own parameterized monitor. Perhaps there is a case if the different transaction types all share a common base class that you access with virtual methods, it might work.


class my_monitor #(type T) extends uvm_monitor;
T trans;
...
endclass

Thanks God. Someone understands my question. So, you are saying that monitor is a parameterized class as it can have multiple transaction types & interfaces with multiple analysis port?

Thanks for your response. I will post my question on Accelera and see what they say.

In reply to Lina.Lin:

In reply to verif_learner:
Here is my understanding:
Usually the monitor is used to collect the transactions from the bus interfaces and do checks and coverage etc. there or send the transactions to analysis components like scoreboards through analysis ports. You have freedom to instance the monitor in an agent or in an sub-system environment component which depends on your test bench architecture. You also have freedom to collect one type transaction or multiple type transactions in one monitor.
If you want to have one monitor which can be reused for multiple instances with different transaction type, maybe you can consider to implement your own parameterized monitor.


class my_monitor #(type T) extends uvm_monitor;
T trans;
...
endclass

In general, this will not work, except as a common base class to set up analysis ports, which is exactly what the uvm_driver class does with sequence item ports. You are using different transaction types most likely because they have different fields that you need to fill. So the monitor needs to be specialized to the transaction class it’s going to deal with.

In reply to dave_59:

Dave, yes, if analysis port is needed, it can be setup in my_monitor class.