Test hanging inside ethernet driver transaction function: while loop

Below is my task from driver for driving Ethernet packet to DUT:


task drive_transfer(packet_pkt);   //packet is transaction item
byte unsigned_bytes[];
int pkt_len,i=0,packet_size;
int position_dvaln=1;//Increment until it matches value for driving data valid low 

pkt_len = pkt.pack_bytes(bytes);   //get Ethernet packet packed in bytes
packet_size = bytes.size();        //get Ethernet packet size

  while(i <= packet_size)


   if(position_dvaln == (pkt.dvaln_pos))//Deassert data valid for current X'fer  
   begin
       while(pkt.dvaln_cycle!=0)
       begin
         vif.cb.sig_dval <= 'b0;  //keep data valid low for dvaln_cycle clkcycles
         @(vif.cb);
         pkt.dvaln_cycle --;
        end
    end

   else 
   begin
        vif.cb.sig_dval <= 1'b1;
   end
  
   i=i+4;
   position_dvaln++; //keep incr by 1 until it matches value to deassert data valid


    end

end

Here, once the condition is met for driving data valid low (first in in while loop), it enters the loop for keeping data valid low for x cycles.

But it doesn’t complete the loop and hangs on 2nd loop execution.

On commenting vif.cb.sig_dval <= 'b0; inside while loop it completes test, else it hangs.

Is there any race condition?

Where does packet_size change inside of the while(packet_size) loop? If packet_size never changes, I see no way of exiting the while(packet_size) loop. Is there something missing?

In reply to cgales:

Sry code was missing while(i<=packet_size),

I have updated code.

For eg. if pkt.dvaln_pos = 17, then for first 16 X’fer dval <= 'b1 is driven. After that IF condition is triggered, it enters the while loop drives the dval<='b0; but hangs after that waiting for posedge of clk(clocking block).

If I don’t drive dval<=0 in the if condition, ten same logic/loop works well and completes the test.

I am unable to understand how is driving dval<=0 is hanging test?

In reply to RushilMithani_37:

Can you post the code for your interface?

In reply to cgales:

interface ethernet_if(input sig_clk,sig_reset); //clk generation and reset set/unset in top

logic sig_sop;
logic sig_eop;
logic [31:0] sig_data;
logic sig_dval;
logic [3:0] sig_mode;

modport ethernet(input sig_clk, sig_reset, clocking cb);

clcking cb @(posedge sig_clk);
default output #1ns;

output sig_sop,sig_eop,sig_data,sig_dval,sig_mode;
endclocking

endinterface : ethernet_if

In reply to RushilMithani_37:

Can you use blocking assignment instead of non blocking inside the task. Since you are using a task which executes sequentially it is always better to use blocking assignments.

Replace
vif.cb.sig_dval <= 'b0;
with
vif.cb.sig_dval = 'b0;

In reply to RushilMithani_37:

Please include print statements on both the while Loop and post the output here . Now its difficult to comment where actually test is hanging.
Also display i value in print statements