UVM_DRIVER- Driving an interface at an event

Hi,

My agent needs to drive a “done” signal when any some input is received on any one of the two input interfaces. I am using analysis ports to get input transactions and pushing that data on a queue for both cases. I tried to use the event data type but am not able to properly drive the done signal.

input1_data_type _input1[$];
    input2_data_type _input2[$];
    event input1_received;
    event input2_received;

    virtual function void write_input1 (input1_data_type _trans);
        _input1.push_back(_trans);
        ->input1_received;
    endfunction: write_input1

    virtual function void write_input2 (input2_data_type _trans);
        _input2.push_back(_trans);
        ->input2_received;
    endfunction: write_input2
 
    //Not showing the build_phase where I retrieve the interfaces and connect the analysis ports.   

    virtual task run_phase (uvm_phase phase);
        super.run_phase(phase);
        fork    
            //Other tasks
            drive_done();
        join_none
    endtask: run_phase

        virtual task drive_done();
        forever begin
            @(input1_received.triggered || input2_received.triggered)
                output_interface_vif.done <= 1'b1;
            end
        endtask

The above code does not drive the done back to 0 at the next clock. Note I am not able to compile with “##1” as I get the error:

Cycle delay operator requires a default clocking to be specified for
module/interface/program ‘vcs_paramclassrepository’.

The clk and reset are not driven by this agent and I think I can’t specify the timeunit(which I think is what the error is indicating) in this class as it is central to the whole testbench and is likely to change.

I also tried the following but it is not driving interface at all even though I can see transactions being pushed on the queue.

virtual task drive_done();
        forever begin
            @(output_interface_vif.monitor.clk);
            if(input1_received.triggered || input2_received.triggered)
                output_interface_vif.done <= 1'b1;
            else
                output_interface_vif.done <= 1'b0;
        end
    endtask

Can someone suggest a good way to make this work?

In reply to Pooja Pathak:

To be clear, are you writing SV or UVM code?
I see only SV code.
Of course you can use any SV construct in the UVM. But it is recommended to ue the UVM consructs like uvm_event and instead of queues the uvm_tlm_fifo.

The cycle delay operator (##1) might not be supported by VCS. Instead you could use a task which is providing this delay.

task automatic cycles(int unsigned N);
  repeat (N) @(output_interface_vif.monitor.clk);
endtask