Wait statement code optimization

Hi,
I would like to optimize the below code what will be the best way to do it?

  ________________________________________
   parameter NO_OF_ROWS = 5;   
   _________________________________________
   int counter1[`NO_OF_ROWS];
   int counter2[`NO_OF_ROWS];
   task initialize_counter();
     forever begin
       #1;
       fork 
         begin 
           wait((counter1[0] && counter2[0]) == 0)
         end
         begin 
           wait((counter1[1] && counter2[1]) == 0)
         end
         begin 
           wait((counter1[2] && counter2[2]) == 0)
         end
         begin 
           wait((counter1[3] && counter2[3]) == 0)
         end
         begin 
           wait((counter1[4] && counter2[4]) == 0)
         end
       join
     {counter1,counter2} = 0;
   endtask : initialize_counter
  
   task update_counter(int i);
     @(posedge valid)
     counter[i]++;
   endtask : update_counter


What would be the best way to write initialize_counter task so that the same task can be used if NO_OF_ROWS value increases. I do not want to keep adding the same wait statements.

In reply to manasa-n:


task initialize_counter();
forever begin
#1;
    for(int i = 0; i < NO_OF_ROWS; i++)begin
      automatic int j = i;
      fork 
        begin
          wait((counter1[j] && counter2[j]) == 0);
        end 
      join_none;      
    end
    wait fork;
{counter1,counter2} = 0;
end
endtask : initialize_counter


In reply to manasa-n:
Please use code tags to make your code easier to read. I have added them for you.

Also {counter1,counter2} = 0; is not legal syntax, but the following is

counter1 = (counter2 = '{default:0});

You can use the result of an assignment as an expression if you surround it with ()'s