It is perfectly legal to specify default values.
In Verilog the last assignment 'wins'.
- For non blocking assignments that means only the last one is executed.
- For blocking assignments they are executed in the order they are encountered.
In fact in complex state machines it is a method I prefer.
You can use it in both combinatorial (blocking) and clocked/registered (non-blocking) code.
However it is good coding practice to flag this so the reader
knows you are setting defaults and that those values can be override further down in the code. Here a is a snippet from a UART transmitter:
// Defaults for TX FSM
nxt_tx_state = tx_state;
nxt_tx_bit_cnt = tx_bit_cnt;
nxt_tx_samp_cnt = tx_samp_cnt;
nxt_shift_out = shift_out;
The same holds when you have a bottom-all-overriding assignment:
....
....
// This overrides all the above
if (emergency_halt)
state <= IDLE_STATE;
How does the synhtesis tool process this default value? Or is not something I dont have to look at
You don't have to worry about it. Most important is that the simulation and the hardware behave in the same way.
But I'll answer anyway. Simplest is to give an example:
always @(*)
begin
// default
A = 1;
if (B==2)
A = 3;
if (B==4)
A = 5;
end
The synthesis tool translates this into:
if (B==4)
A = 5;
else if (B==2)
A = 3;
else
A = 1;
In this case the two 'if' statements are mutually exclusive but even if that is not the case the result will be that the hardware behaves as the blocking assignments: The last one wins.