Electronic – Flip-flop vs combinatorial description – what exactly is the difference

fpgaverilog

I was going through some reference design from Altera's Wiki and ran into the following piece of code:

always @* begin
   in_ready <= out_ready || ~out_valid;
end

My understanding is that having a flip-flop like that helps get more deterministic timing, synthesis tool can refuse to synthesize if out_ready || ~out_valid combinatorial delay exceeds the limit and timing requirements are not met etc. Other than that, that should be en equivalent of the following combinatorial description:

assign in_ready = (out_ready || ~out_valid);

What made me think about it is the larger piece of code that I am readying. Sometimes combinatorial logic is used to drive the "ready" output of some modules, but sometimes this style. I cannot really spot a functional difference and see an obvious explanation.

I've read somewhere that combinatorial logic is not welcome in FPGAs because of timing issues and synchronized design is always preferred, and this project specifically targets FPGAs. But the mixing is what confuses me. So two questions popped out in my head:

  1. When and why one solution should be preferred over another?
  2. Is there any difference in behavior (or analysis of the design) when the output of the module is "reg" versus when it is a "wire"?

Any help is appreciated. Thank you.

Best Answer

If you use a flip flop, then changes in the combinational logic will only "appear" on the output of the flop on a clock edge. In general, with combinational logic, you will get all sorts of spurious transitions while the logic is "settling" on it's eventual value. If spurious transitions are a bad thing in your overall design (most likely they are), you will want to "filter them out" using a flip flop in this way. These transient changes in combinational outputs when inputs change are generally called "hazards."

In terms of the hardware you are generating in both cases, you will get the same combinational logic generated in your FPGA in both cases (out_ready || ~out_valid). The difference is, in the one case you are simply aliasing the output net of the combinational logic with the name in_ready, whereas in the other case you are connecting the output of the combinational logic to the input of a clocked flip flop.

In summary, there's nothing wrong with combinational logic, and you'd be hard pressed to design something useful in an FPGA that didn't include a bunch of it. Running the output through a flip flop isolates the next "stage" (i.e. the consumer) of your logic from seeing the spurious transitions of that logic that happen inherently when the inputs change (this design pattern, incidentally, is what pipelining - e.g. in modern CPUs - is all about). Remember to think of FPGAs and digital logic as hardware when writing Verilog (because that's what they are after all)!

Also, on a sidenote, determinism is not something that is measured on a sliding scale - something either is or is not deterministic, end of story.