Clock Monitoring

Hi,
I have a clock uvm_agent to control the clock. In uvm_sequence_item I can among other things determine how many cycles the clock should run. My DUT is a simple counter, it means output is dependent on how many cycles the clock is running, so I have to pass this information to my reference model.

So now I wonder, how I should build the monitor for this agent.
Observing only the clock pin, I could not determine how many cycles it would be, then I think there will be a need to create transactions for every single cycle.
Another solution I came up with is to directly connect the uvm_sequencer with uvm_monitor and simply pass the request item.

What would be the best practice?

In reply to Mariusz:

It is not a useful idea to stop your simulation by shutting down the clock. Use another stop criteria like the max count you want to reach. Then your clock is running without any limitation.
Following your idea it is impssible to connect the sequencer simply to the monitor. The monitor does not have the adequate mechanisms available. And the connection between sequencer and driver ia a one-to-one connection.

Thanks for your reply. Your solution sounds good, but what if the DUT does not explicit put out its counter output (i.e. I should make a stimulus sequence to take that value)?
In my previous approach, I wanted to wait for a random number of cycles, read the value, and further run for the next random number of cycles.
It would be good if I put another counter in the HDL next to the DUT for counting down these clock cycles?

In reply to Mariusz:

I do not really understand what you are saying. Could you post an example on the EDAplayground please?

So for a simple example, I have a DUT like that:
(simple counter, but data can be only read when read pin changed value from 0 to 1)


module DUT( 
  input logic clk,
  input logic rst,
  input logic read,
  output logic [7:0] data_out
);
  
  logic [7:0] data_internal;
  
  always @(posedge clk, posedge rst) begin
    if(rst) 
      data_internal <= 0;
    else
      data_internal <= data_internal+1;
  end
  
  logic read_last;
  
  always @(posedge clk, posedge rst) begin
    if(rst) begin
      read_last <= 0;  
      data_out <= 0;
    end 
    else begin
      read_last <= read;
      if( read & !read_last )
        data_out <= data_internal;
    end
  end
endmodule

Here I cannot wait for the event from the DUT, because to read output data I have to firstly set the read pin. So I wonder how to wait for a specified time (e.g number of cycles specified by test), and also pass that information to the monitor, so I could predict the value in the reference model.
Then I would read data and compare output from DUT and reference model.

In reply to Mariusz:

You could monitor the data_internal simply with an assertion, checking for a certain count.

In reply to chr_sue:

Thank you, I thought that I cannot use internal signals in DUT.
But I am still a little confused because I want to check if that counter counts correct. If I would simply wait for the value of the counter in DUT, then I would not know if it gets to that value correct (e.g step may be wrong).
So, I wanted to wait for a specified period of time, and compare that value with the predicted value.
Is it a bad approach?

In reply to Mariusz:

A (hifh-level) reference model does not know anything about clock cycles. It works with transactions. Only in the DUT you have the clockcycles.
I think a counter is not a good example for dealing with the UVM.