Fork join to generate clocks

I am trying to generate 3 different clocks with different periods using a fork join. even period =main/2 and odd period =main/3. When I execute this code, clka and clkb are toggling with same period as clkc (odd period) which is not expected

// this is inside a module and has the calculation for period before forever
    initial begin
    //code to calculate periods.
    forever 
    fork
    #(main_period) if (reset_n==0) clka = ~clka;
    #(even_period) if (reset_n==0) clkb = ~clkb;
    #(odd_period)  if (reset_n==0) clkc  = ~clkc; 
    join 
    end
   end

Can anybody please help understand the above behavior why all clocks are toggling with odd period?
I see the correct output if i move forever inside fork…join and keep 3 different forever blocks for each clock.

In reply to svq:

Because of the join, with the forever, at the end of the longest statement you immediately refire the three statements. Any statement that terminates before the one that lasts longer does nothing, does not retoggle, until all the one that has the longest time ends.

Ben systemverilog.us

In reply to svq:

I believe they should have written this as

initial begin
    //code to calculate periods.
    fork
    forever #(main_period) if (reset_n==0) clka = ~clka;
    forever #(even_period) if (reset_n==0) clkb = ~clkb;
    forever #(odd_period)  if (reset_n==0) clkc  = ~clkc; 
    join 
    end
   end

In reply to ben@SystemVerilog.us:
Thanks Ben for the explanation. In that case, if I had used join_none instead of join,it would have given expected outputs, right?

In reply to dave_59:

Thanks Dave. Yes moving the forever inside fork does the trick.

In reply to svq:

In reply to ben@SystemVerilog.us:
Thanks Ben for the explanation. In that case, if I had used join_none instead of join,it would have given expected outputs, right?

No, that would not work because at the end of the shortest thread, a new set of 3 threads would be initiated, thus 2 new threads would collide with the existing not yet completed threads.
Ben systemverilog.us

Hi!I tried svq’s code on edaplayground and I didnot face the issue. I see all three clocks toggling as expected. Is this how simulator handles?
I used forever begin instead of how SVQ has used forever.

In reply to to_learn_uvm:

That all depends on what you are expecting and what you actually wrote. Can you show the actual code you wrote?

In reply to to_learn_uvm:

That code from the original question gives you three different clocks with same period (60). But svq wanted 3 different periods. That requires the code I showed above.

Okay, thanks Dave.