Simulation hangs

Hi,

I try to simulate the following code, but it hangs forever, don't know why?
Could you please help me out. But it runs when forever block got removed.
class timer_control;

//function timer_load (input bit cpu_timer_ld_dn, gate_rise_edge, 
task timer_load (input bit cpu_timer_ld_dn, gate_rise_edge, 
                 input bit [ 2:0] timer_modes,
                 ref bit load_timer_reg);
  case (timer_modes)
    3'd0 : load_timer_reg = cpu_timer_ld_dn;
    3'd1 : load_timer_reg = gate_rise_edge;
    3'd2 : load_timer_reg = (cpu_timer_ld_dn | gate_rise_edge); 
    3'd3 : load_timer_reg = (cpu_timer_ld_dn | gate_rise_edge); 
    3'd4 : load_timer_reg = cpu_timer_ld_dn;
    3'd5 : load_timer_reg = gate_rise_edge;
    //3'd0 : return (load_timer_reg = cpu_timer_ld_dn);
    //3'd1 : return (load_timer_reg = gate_rise_edge);
    //3'd2 : return (load_timer_reg = (cpu_timer_ld_dn | gate_rise_edge)); 
    //3'd3 : return (load_timer_reg = (cpu_timer_ld_dn | gate_rise_edge)); 
    //3'd4 : return (load_timer_reg = cpu_timer_ld_dn);
    //3'd5 : return (load_timer_reg = gate_rise_edge);
  //default: return (load_timer_reg = 1'b0);
  default: load_timer_reg = 1'b0;
  endcase
endtask
//endfunction

endclass

module test;

bit cpu_timer_ld_dn, gate_rise_edge;
bit  [ 2:0] timer_modes;

bit load_timer_reg;

initial
begin
  cpu_timer_ld_dn = 1'b0;
  gate_rise_edge  = 1'b0;
  timer_modes     = 3'd0;

  #40;
  cpu_timer_ld_dn = 1'b1;
  #40;
  cpu_timer_ld_dn = 1'b0;
  #40;
  $stop;
  $finish;
end

initial
begin
  timer_control control; 
  control = new();
  
  forever
  begin 
    control.timer_load(cpu_timer_ld_dn, gate_rise_edge, timer_modes, load_timer_reg);
  end
end

endmodule

In reply to senthil_m:

if you are calling any task which is completing in zero time( no delay in task)in the forever loop it will be hang.
try to add delay like #1 in the task.

In reply to murali.gubba:
Although adding #1 inside the task eliminates the hang, it is not a very efficient way of coding. What you want to is have timer_load execute whenever an input argument changes. For that you can do

forever @(*)
  begin 
    control.timer_load(cpu_timer_ld_dn, gate_rise_edge, timer_modes, load_timer_reg);
  end

Also, it is better to use functions for procedures that are not time consuming. Declare the return type of the function as void if you do not want it to return a value.

In reply to dave_59:

Thanks for your reply, after inserting #1 delay task is running fine. Also tried for
functional call but it works only if add @ (cpu_timer_ld_dn) insid\ inside the forever block.

also forever @ (*) end up with syntax error, guess forever should be used only inside the
initial block.

initial
begin
timer_control control;
control = new();
forever
begin
@ (cpu_timer_ld_dn);
control.timer_load(cpu_timer_ld_dn, gate_rise_edge, timer_modes, load_timer_reg);
end
end

Anyhow you have solved my issue & thanks a lot, now only I came to know about
zero delay task wont run inside a forever block.

Thanks

In reply to murali.gubba:

Thanks for your help, now my task is running fine.

In reply to senthil_m:

Sorry for my mistake. forever @ (*) inside the initial block is working fine.

Thanks