'run' task of monitor is being run before that of driver

hi all
i am new to ovm…i’ve just begun with a counter verification…my environment consists of a driver and a monitor only for the time being…
the problem i’m facing is that, ‘run’ task of monitor is executed before that of driver…

can anyone please help…

//-------------------------this is my code--------------------------

//-----------interface------------
interface intfCounter(input bit clk);

logic data, rst;
logic [2:0] count;    
modport test(input count, output data, rst);
modport dut(output count, input data, rst);

endinterface

//--------------------top module------------------
module top;

logic clk=0;

initial begin 
forever 
#50 clk = ~clk;
end 

intfCounter intfc(clk);     
my_test t1;
count_ones cnt1(.clk(clk), .reset(intfc.rst), .data(intfc.data), .count(intfc.count));     
 
 initial begin
 run_test("my_test");
 end

endmodule

//-------------------test class--------------------
class my_test extends ovm_test;

`ovm_component_utils_begin(my_test)
`ovm_component_utils_end

my_env env;  
virtual interface intfCounter intfc_t;

function new (string name = "my_test", ovm_component parent);
    super.new(name, parent);
endfunction

function void build();
    super.build();
    env = my_env::type_id::create("env", this); 
endfunction

virtual function void connect();       
   env.assign_vi(intfc_t);
endfunction
task run();    
    $display("--------enter test-------");
    #500ns;   
    $display("----------exit test-------");
    global_stop_request();
endtask: run

endclass: my_test

//------------------------environment---------------------------
class my_env extends ovm_env;

my_driver drv;
my_monitor mntr;

virtual interface intfCounter intfc;

`ovm_component_utils(my_env)

function new(string name = “my_env”, ovm_component parent);
super.new(name, parent);
endfunction: new

virtual function void build();
super.build();
drv = my_driver::type_id::create(“drv”, this);
mntr = my_monitor::type_id::create(“mntr”, this);
endfunction: build

function void assign_vi(virtual interface intfCounter intfc_e);
drv.assign_vi(intfc_e);
mntr.assign_vi(intfc_e);
endfunction

function void connect();
super.connect();
endfunction: connect
endclass

//-------------------driver----------------------
class my_driver extends ovm_driver();

virtual interface intfCounter intfc;    

`ovm_component_utils (my_driver);

function new (string name = "my_driver", ovm_component parent = null);
    super.new(name, parent);
endfunction: new   

function void assign_vi(virtual interface intfCounter intfc);    
this.intfc = intfc;
endfunction

function void build();
     super.build(); 
endfunction: build  
              
task reset_DUT();   
	$display("----enter reset_DUT task------");
    intfc.rst = 1;
    intfc.data = 0;
    repeat(1) @(posedge intfc.clk);                  
    intfc.rst=0;
    $display("----exit reset_DUT taskt------");

endtask:reset_DUT

task run();
$display(“-------enter driver at time = %x\n--------”, intfc.clk);
reset_DUT();
fork
drive_dut();
join
$display(“-------exit driver--------”);
endtask: run

task drive_dut();
forever begin
@(posedge intfc.clk);
$display(“-------enter drive_dut task at time = %x\n--------”, intfc.clk);
intfc.data <= 1’b1;
end
endtask: drive_dut

endclass: my_driver

//-----------------monitor-------------------

class my_monitor extends ovm_monitor;

virtual interface intfCounter intfc;

`ovm_component_utils(my_monitor)

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

function void assign_vi(virtual interface intfCounter intfc);
this.intfc = intfc;
endfunction

function void build();
super.build();
endfunction: build

virtual task run();

$display("-------enter monitor---------");  
fork
    read_count();
join

endtask: run

task read_count();
bit [2:0] count_at_monitor;
forever begin
@(posedge intfc.clk);
count_at_monitor = intfc.count;
$display(“count = %b”, count_at_monitor);
$display(“-------exit monitor---------”);
end
endtask

endclass: my_monitor

can you post the display along with timestamps? That will help.

The order of the start of run() phases is indeterminate. There should be no reason why the monitor could not be started before the driver, or after the driver.

Are you having a specific issue caused by the order in which the driver and monitor are being started?

Please note that there should not be time difference between the start of two runs.
But within that they can start at any time. I dont think OVM guarantees any sequence
or it is preferable to keep your design dependent on that …

The order of the start of run() phases is indeterminate. There should be no reason why the monitor could not be started before the driver, or after the driver.
Are you having a specific issue caused by the order in which the driver and monitor are being started?

No specific issue caused by the order of execution…but should’n the flow of execution of execution be like this…
test → environment → sequencer → driver and monitor ??

The run() method of each component is forked as a thread from the main thread. Since it is up to the simulator to schedule thread execution, the sequence of their execution is unknown. By following the OVM requirements, you will never have any issues with this.

No specific issue caused by the order of execution…but should’n the flow of execution of execution be like this…
test → environment → sequencer → driver and monitor ??

If that is what you want, you should take care in your components (using appropriate events)
just the way hardware modules do. They all start after reset and everything else depends on the way you want the design to behave

The run() method of each component is forked as a thread from the main thread. Since it is up to the simulator to schedule thread execution, the sequence of their execution is unknown. By following the OVM requirements, you will never have any issues with this.

Ok…Thankyou sir…

The run() method of each component is forked as a thread from the main thread. Since it is up to the simulator to schedule thread execution, the sequence of their execution is unknown. By following the OVM requirements, you will never have any issues with this.

I am an OVM newcomer…
where can I find those OVM requirements?
Can you give an example how to run those tasks together after some event?
regards
ze’ev

If that is what you want, you should take care in your components (using appropriate events)
just the way hardware modules do. They all start after reset and everything else depends on the way you want the design to behave

Hi,
You should take care of the timing. I suppose that you will miss the transaction in the first clock. so you need to take care of the latency in the monitor or ignore the first transaction. Remember in OVM all the run tasks are forked together. so it is the users reponsibility to take into account the latency. Also I would suggest you to have some event or a bit like enable monitor which should be set after the first transction is driven.

Hope it helps.

With Regards
Bala

There is no reason that you should miss the transaction in the first clock. All ovm components are created and running at time 0, so they are all running when clock events start happening.

Any monitor connected to the DUT should have knowledge of the DUT reset state, usually by connecting to the appropriate reset signal of the DUT.