2
votes

We have a designer here that has assigned a temporary result to a variable in a combinational always block in order to improve readability. His code looks similar to this:

logic second_condition;

always_comb begin
  if (condition) begin
    second_condition = long_statement;
    if (second_condition) begin
      (...)
    end
  end
end

The problem here is that second_condition arguably describes a latch, but since this latch has no load (it's not used in any other always block), it is optimized away, and there is no warning about latches being inferred during synthesis. Some tool vendors seem to call this a "hanging latch". Notably a loop iterator can also be considered a hanging latch.

Is this something that is completely safe with all tools, or is it worth having a coding guideline never to do this? In this case you could just add an assignment to zero in the top of the always_comb block to remove the "hanging latch".

2
I have used it, although rarely, in ASIC designs without any adverse effects. Nowadays I prefer to make it an independent 'assign' outside the always which works in the same way but does not have the implied 'latch threat'. - Oldfart
Seems like a gamble to me. Even if it's 'safe' today... doesn't mean an issue won't pop up someday as tools get updated, new tools come along etc. - ajcrm125
For the sake of maintainability, I would recommend never using code if it isn't completely clear what will be produced by the synthesis engine. If statements without either an else statement or a default declaration of output values prior to the if statement describe a latch. Depending on the synthesis engine to override what you've written on the basis of the always_comb is a bad idea. Plus what happens if someone needs to convert this code back to regular Verilog at some point? (For example, Xilinx's Vivado tool still can't use SV for the top level of custom IP blocks). - Barry Moss

2 Answers

1
votes

In your code you are creating a latch with condition & second_condition. None of those define the latch load. The load is applied to somewhere inside (...) which you forgot to specify.

always_comb is a contract with system verilog and it is supposed to guarantee that there is no latch in the block. Any SV compiler should error-out if it sees this code. Check your log file, might have warnings instead. Should be an error.

if you need latches, use always_latch instead.

If you worry about the temp variable, synthesizer should optimize it away (if it is a good synthesizer :-)).

-2
votes

Since second_condition is an intermediate signal that is completely contained within the always_comb block, declare it within the always_comb block.

always_comb begin
  logic second_condition;

  if (condition) begin
    second_condition = long_statement;
    if (second_condition) begin
      (...)
    end
  end
end

Presto! No need to fear any pesky "hanging latches".