How to write fork join run parallelly in UVMF with forever

  1. I am trying to make two fork and join/join_any to run parallelly within a same sequence. but due to forever it wont come out of the first fork join_any. Any way to run both fork’s run parallelly ?? 1 fork for clock(always run) and another fork for data(user depends).
    fork
      begin // thread 1 for clock generation continuously
      forever
         begin
           rs422_485_agent_directed_seq.req.rs422_rx = 1;
           rs422_485_agent_directed_seq.start(rs422_485_agent_sequencer);
           #100ns;
           rs422_485_agent_directed_seq.req.rs422_rx = 0;
           rs422_485_agent_directed_seq.start(rs422_485_agent_sequencer);
           #100ns;
         end
      end
    join

    fork
      begin // 2nd thread Test stimulus data inputs via register or user task
        pcie_a_mem_write(32'h3000B008, 32'h00000001);
        pcie_a_mem_write(32'h3000B00C, 32'h00000001);
        pcie_a_mem_write(32'h3000B004, 32'h00000001);
        pcie_a_mem_write(32'h3000E000, 32'h00000002);
      end     
    join
  1. Also i tried within a same fork/join_any by using two threads as below, but facing the issue in timing difference between the threads. clock generation will get affect due to data generation or vice versa.
    fork
      begin // thread 1 for clock generation continuously
      forever
         begin
           rs422_485_agent_directed_seq.req.rs422_rx = 1;
           rs422_485_agent_directed_seq.start(rs422_485_agent_sequencer);
           #100ns;
           rs422_485_agent_directed_seq.req.rs422_rx = 0;
           rs422_485_agent_directed_seq.start(rs422_485_agent_sequencer);
           #100ns;
         end
      end

      begin // 2nd thread Test stimulus data inputs via register or user task
        pcie_a_mem_write(32'h3000B008, 32'h00000001);
        pcie_a_mem_write(32'h3000B00C, 32'h00000001);
        pcie_a_mem_write(32'h3000B004, 32'h00000001);
        pcie_a_mem_write(32'h3000E000, 32'h00000002);
      end 

    join_any

In reply to sandeepasm:

Please use code tags making your code easier to read. I have added them for you.

A fork/join or a begin/end with a single statement behaves the same as a single statement alone. So your first code snippet is essentially a forever loop followed by a series of calls to pcie_a_mem_write. Since the forever loop never ends, the call never happen.

We don’t know what inside pcie_a_mem_write, and we can’t understand what you mean by issues in timing differences in the second code.

In reply to dave_59:

Thanks for the reply.

Requirement is to generate the clock and data within a sequence with continuous clock, So tried with forever and yes i agree it is not coming out of the forever loop.

In the 2nd snippet of code, 1st thread and 2nd thread is running parallelly but with time delay. when it shifts from 1st thread to 2nd and come back to the 1st it takes time. due to this clock period is getting affected from 100ns period to 87ns only during PCIe transactions.

2nd thread basically a PCIe transaction used by questa QVIP - mentor (rc_serial), it is a read/write transaction nearly takes 1us time/transaction. i am not sure due to pcie it takes time delay or not.

But when simple task is called in 2nd thread instead of PCIe read/write it is also taking some delay , due to that clock generation affect only during 2nd thread/task is in execution.

i tried to upload a waveform but not successful.

In reply to sandeepasm:

Creating your clock signal in this way is not useful. The sequence might define how the clock will start, i.e. as high or low pulse. All what comes afterwards is the task of the driver which will generate the clock signal. You do not need a forever loop in this case. And the time delay in the sequence is not useful.
This makes your application pretty simple.