Why does the Verilog simulator handle these cases differently?
1)
always #1 clk =! clk;
initial
begin
@(posedge clk)
start <= 1;
end
initial
begin
clk <= 1;
start <= 1;
end
The literature says that in 1 case, the clk and start signals will be set simultaneously and clk can capture the start signal only on the next edge. That's how it works.
But why is the second case different from the first? After all, nonblocking assignments should also be set at the same time. But it doesn't work as in the first case. But if you write it like that, then it works like the first case.
2)
initial
begin
clk = 1;
start <= 1;
end
Example 1)
module test();
reg clk=0;
reg start=0;
reg flag=0;
always #1 clk =! clk;
initial
begin
#5;
@(posedge clk)
start <= 1;
end
always@(posedge clk)
if(start)
flag<=1;
endmodule
module test();
reg clk=0;
reg start=0;
reg flag=0;
initial
begin
#5;
clk <= 1;
start <= 1;
end
always@(posedge clk)
if(start)
flag<=1;
endmodule
Simulation results
Your code examples do not follow recommended coding style for synchronous logic. This leads to simulation race conditions.
You should expect different results with these different code samples.
You are mixing coding styles. You should generate the clock with the blocking assignment (=
) in an always
block. Since start
and flag
are synchronous to clk
, they should both use nonblocking assignments (<=
) and be aligned with the clock (@(posedge clk)
):
module test();
reg clk=0;
reg start=0;
reg flag=0;
always #1 clk = !clk;
initial
begin
repeat (3) @(posedge clk);
start <= 1;
end
always @(posedge clk)
if (start) flag <= 1;
endmodule