Always @ * a block with one non-blocking purpose - good, bad or inappropriate?

The general rule of thumb mentioned in all the books I've read so far is that you need to use non-blocking assignments always in blocks that are controlled by the rising or falling edges of the clock. In contrast, blocking assignments should be used to describe combinatorial logic. This rule makes sense to me, and the authors of the examples carefully follow it.

However, I noticed the following Verilog snippet in one of the production code:

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

Note that the non-blocking assignment <= . I don’t think it has any meaning in this case, because there aren’t several assignments. However, I cannot find an explanation. Thus, the question is whether it has or does not make any difference, as in the field of a given block always and as part of a larger project?

+7
source share
3 answers

Obscene, but bad practice.

I doubt that one appointment causes any side effects. The block will always be triggered for any changes on the right side, updating in_ready. There is nothing to block, so non-blocking will not cause problems.

If a larger project had:

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

I am not sure, because it is combinatorial, but an additional delta step may be required to solve.

+4
source

Of course, this violates my directive number 3: http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf ), but it will work.

The reason to avoid using non-blocking assignments for combinational code logic is simulation performance. In the Munkymorgy example, after triggers always, you evaluate the right-hand side (RHS) of all the equations, return to the top of the block always, refresh the LHS of the equations, which again will always cause the block, which will again cause the simulator to evaluate the RHS of the equations, go to the top of the always block, and then update the LHS equations. For large blocks, this can lead to several iterations through an always block with a corresponding modeling penalty.

In your simple 1-line example, there is no internal penalty for the simulation, but in other places there may be penalties for cross-assignment.

Good coders use consistently good coding habits. I would change the code. If changing the code violates the simulation results, then there are additional incorrect coding habits buried elsewhere in the code. The code should not be fragile.

Regards - Cliff Cummings - Verilog and SystemVerilog Guru

+7
source

its a good choice if you understand how the circuit will behave very well for example,

always @ * starts b <= a + s; a = b; end

  • therefore, in this code example, a complete circuit developed always inside a block is activated when something inside the sensitivity list, which all inputs will either rise or fall, changes its current state.
  • now b <= a + c now here the full adder will be created with 'a' and 'c' as input, but
  • now the design is being executed or the compiler synthesizes the circuit so that the next operator a = b here the wire is taken from the old value, and not from the updated b, and was provided; so simple
  • If you want this to happen, you can not make any problems in synthesized
+1
source

All Articles