There is nothing nondeterministic about the final value of A
in your code, not for simulation, not for synthesis.
However, to be absolutely exact, there is a possible simulation-synthesis-mismatch if the design contains a trigger on A
. Consider the following example:
module test(input clk, output reg a, b);
always @(posedge clk) begin
a <= 0;
a <= 1;
end
initial b = 0;
always @(posedge a) begin
b <= !b;
end
endmodule
And a test bench:
module tb;
reg clk = 0;
always #5 clk = ~clk;
wire a, b;
test uut (clk, a, b);
initial begin
$monitor("clk=%b a=%b b=%b", clk, a, b);
repeat (100) @(posedge clk);
$finish;
end
endmodule
During simulation both updates a <= 0
and a <= 1
are pushed to the NBA events region and are executed in-order, so a
always ends up being set. However, as the a <= 0
is executed as well, there is a negative pulse with zero width on a
for every clock cycle. This pulse triggers the 2nd always block. This is the simulation output (tested with Icarus Verilog and Modelsim):
clk=0 a=x b=0
clk=1 a=1 b=1
clk=0 a=1 b=1
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=1
clk=0 a=1 b=1
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=1
clk=0 a=1 b=1
clk=1 a=1 b=0
clk=0 a=1 b=0
...
However, in synthesis this will simply assign a
the constant value 1 and b
the constant value zero. (Tested with Yosys and Xilinx Vivado.) So the post-synthesis simulation output looks like this:
clk=0 a=1 b=0
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=0
clk=0 a=1 b=0
clk=1 a=1 b=0
(Theoretically the first line could still say a=x
, but every decent synthesis tool would optimize the a
-flip-flop away, as both tools in the test did.)
Other than that there is no potential issue with that code, and as @Morgan pointed out correctly in his answer, this is a very usual coding technique for defining the "default values" of output signals before encoding the special cases using conditional assignments (using if
and/or case
).