This is a time 0 race condition. Continuous assign statements are in effect like concurrent processes that start at time 0 along with initial blocks. If the initial block begins execution first, then you get the 0 results.
A couple of ways of fixing this are instead of the using the continuous assignments:
use static variable initializations which are guaranteed to execute before any initial or always block.
Hi Dave,
Thank you very much for you timely response.
The solutions you mentioned are working fine.
But my actual requirement is a bit complex than this.
The above mentioned is just a sample code.
I am posting a bit more complex than the above code.
module tb;
bit clk1, clk2, clk3;
bit [3:0] cnt1;
bit [3:0] cnt2;
bit clk1_2nd_pos_to_102_pos;
bit clk2_2nd_pos_to_102_pos;
initial begin
forever begin
#10 clk1 = !clk1;
end
end
initial begin
forever begin
#15 clk2 = !clk2;
end
end
initial begin
forever begin
#5 clk3 = !clk3;
end
end
task counter(bit [3:0] count, bit clk_local, enable);
@(posedge clk_local);
if(enable)
count = count + 1;
else
count = 0;
endtask
task sec_to_102_edge_det(bit clk_lc, bit enable);
if(!enable) begin //{
repeat(2)
@(posedge clk_lc);
enable = 1;
end //}
else begin //{
repeat(100)
@(posedge clk_lc);
enable = 0;
end //}
endtask
initial begin
fork
forever counter(cnt1, clk1, clk1_2nd_pos_to_102_pos);
forever sec_to_102_edge_det(clk1, clk1_2nd_pos_to_102_pos);
forever counter(cnt2, clk2, clk2_2nd_pos_to_102_pos);
forever sec_to_102_edge_det(clk2, clk2_2nd_pos_to_102_pos);
join
end
initial begin
$dumpfile("dump.vcd"); $dumpvars;
#10000;
$finish;
end
always@(posedge clk3)begin
if(cnt1 < 5)
$display("cnt1 = %d at timee = %t", cnt1, $time);
end
always@(posedge clk3)begin
if(cnt2 < 5)
$display("cnt2 = %d at timee = %t", cnt2, $time);
end
endmodule
You have several significant flaws in you code. I recommend that you read Section 13.3 of the LRM regarding tasks and how they are utilized. Specifically, the direction of formal arguments and the difference between static and automatic tasks.