2
\$\begingroup\$

I feel that I understand sequential logic in Verilog using always blocks triggered on clock edges, and combinatorial logic using assignments to wires is straightforward.

What keeps confusing me is combinatorial always blocks like

reg a;
reg b;
reg c;

always @(*) begin
  a = b & c;
end

Isn't this just the same as making a into a wire and assigning to it?

I understand that combinatorial always blocks can conditionally set an output (if (en) a = b; else a = c;) but that could be implemented as assign a = en ? b : c.

I also get that the combinatorial always block need not set an output, in which case the output will remain unchanged, which requires it to be latched. There are a lot of resources out there suggesting that this is a Bad Thing and are more often than not the result of logic errors.

My question is, is there any logic that requires a combinatorial always block, or is it always possible to use a combination of sequential always blocks and wires instead? And should I feel bad about using latches or are they the best solution to certain problems?

\$\endgroup\$
1
  • \$\begingroup\$ There is a subtle difference between always@* and assign which I guess is no longer relevant after SV introduced 'logic'. \$\endgroup\$
    – Mitu Raj
    Commented Aug 17, 2021 at 5:54

1 Answer 1

1
\$\begingroup\$

is there any logic that requires a combinatorial always block?

It is always possible to reduce any logic to ANDs, ORs, NOTs and DFFs, so the answer would be no. But for convenience and clarity of expression, the ability to use if/then/else and case statements as higher-level abstractions is extremely useful.

And should I feel bad about using latches or are they the best solution to certain problems?

Latches — really, asynchronous state machines in general — should be avoided except when they are absolutely necessary. Especially in FPGA design, which the chips and the tools are highly optimized for synchronous design. But they should also be used with care in ASIC design, too.

For example, I recently created a small module that performs edge detection on an asynchronous input. I used an asynchronous R-S flip-flop followed by a synchronizer and a synchronous edge detector. But from experience, I know that the target technology (Actel FPGA, which is mux-based, not LUT-based) is very well-behaved with this sort of logic.

It isn't even necessary to use the combinatorial always block to create async state machines. It can be done perfectly well with wire assignments only. That just happens to be the way that many people do it unintentionally.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.