2
\$\begingroup\$

Modeling both sequential and combinational logic within the same always block a good practice or is it recommended to code them in separate blocks.

always @(a or b) 
  y = a ^ b;

always @(posedge clk or negedge rst_n) 
  if (!rst_n) q <= 1'b0; 
  else
  q <= y;

Or doing this:

always @(posedge clk or negedge rst_n) 
  if (!rst_n) q <= 1'b0; 
  else
  q <= a ^ b;

I know both would result in same functionality.

But it is also said that mixing blocking and nonblocking assignments in the same always block is a poor coding style. Do we not use blocking for combinational logic and non-blocking for sequential logic.

  1. Modeling both sequential and combinational logic within the same always block a good practice.

  2. Mixing blocking and nonblocking assignments in the same always block is a poor coding style.

Then in that case above statements are contradicting isn't it?

\$\endgroup\$
  • \$\begingroup\$ Up to you. I'd use the latter personally, though with many more begin and end statements. \$\endgroup\$ – Tom Carpenter Nov 18 '16 at 7:22
  • \$\begingroup\$ Thanks Tom. I see that they say its a good practice to have them in same block. Whats good in industry point of view? \$\endgroup\$ – Sai Gautham Nov 18 '16 at 7:37
  • \$\begingroup\$ BTW, the rule about mixing blocking and non-blocking applies to assignments made to the same variable in the same block - not different variables. \$\endgroup\$ – dave_59 Nov 18 '16 at 17:04
  • \$\begingroup\$ Depends on you you ask. Our rule is to never use blocking assignments in a clocked always block, even for "temporary" variables. So I would use option #2 above, but if I use the expression "a^b" more than once and want to assign it to a temporary, it goes in its own block. \$\endgroup\$ – Evan Dec 2 '16 at 4:40
  • \$\begingroup\$ One more style comment: our company style is to never use explicit sensitivity lists for combinatoric blocks. Either use always @(*), or use the system verilog always_comb syntax. \$\endgroup\$ – Evan Dec 2 '16 at 4:42
1
\$\begingroup\$

Mainly opinion based, and below is mine.

Each always block should either implement combinatorial logic or sequential design, but the sequential design may contain expressions that result in combinatorial logic, as long as the result that is assigned is either combinatorial logic or sequential design for all results of the always block. You two examples already adhere to this rule.

Use blocking assignment for combinatorial logic, and non-blocking assignment for sequential design to avoid race conditions between different always blocks driven by the same clock.

Finally, benefit from using an advanced synthesis/simulation tool, and write the code in a way that is most obvious and readable, in order to reduce risk of bugs, and make future maintenance easier. The purpose of having an advanced synthesis/simulation tool is that the tool handles the tedious task of using resources the best way, so you can write the code the easy way. Thus don't write hardware tailored code with the purpose of utilizing resources the best way, except if you are aware of a specific problem, which is probably not the case with your example code.

With your example, I think the single always block is most obvious and readable, so that should be preferred.

\$\endgroup\$
0
\$\begingroup\$

My point of view is that when reviewing code for re-use, optimisation, debugging or just understanding, I tend to focus on the interaction between inputs and outputs and the intermediate signals/states.

I find it the easiest when code is written in such a way that every possible combination of inputs/signals/state affecting an output/signal/state is in close vicinity so that I can understand what the signal/state/output is affected by. Although, this is not always possible, I try and do this wherever it is for ease of review.

So, to summarise, my preference is option 2.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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