Can a logic variable be initialized and separately assigned?

A student asked me a question regarding logic initialization and assignment. The desired code snippet is:

logic a = '1;

always_ff @(posedge clk)
    a <= '0;

This initialization is desired in FPGA design where the initialization is the power-up state of the flip-flop.

My student reports that Mentor and Aldec allow the initialization while Synopsys and Cadence report a multi-driver compilation error. I tried to find the correct behavior in the IEEE Standard and it is somewhat ambiguous whether this coding style is legal. The Standard makes it clear that the logic a = 1; is just an initialization so it seems that making another assignment later would be legal.

Perhaps the compiler is complaining about assignments from multiple procedural blocks(?)

If anyone knows if this was clarified in the 2017 SV Standard, I would appreciate a reference.

This question is regarding the Standard and not specific tools. I want to know what the standard says about this topic.

Regards - Cliff Cummings

In reply to cliffc:

Hi Cliff,

You are correct that the LRM does not consider static variable initializations as a process. However, the Verilog 1364-2001 LRM did consider initializations as initial blocks.

reg A=1;
// equivalent to 
reg A;
initial A=1;

SystemVerilog changed the behavior to say that initialization occurs before any initial or always processes begin (BTW, this is why fork/join_none is not allowed inside a function call initialization). I think some tools still treat initializations as initial processes by inserting them first into the scheduler.

This is further complicated by the SystemVerilog LRM statement:

Software tools should perform additional checks to warn if the behavior within an
always_ff
procedure does not represent sequential logic.

There is no standard for what represents “sequential” logic. I think it is relatively recent that FPGA synthesis tools allow initializations, some even now support initial blocks for initializations.