# Difference in synthesis between bitwise AND (&) and logical AND (&&)

Would these two code snippets synthesize the same way? I know this will be tool dependent because all synthesizers are slightly different. That being said, I think they probably tend to agree on this because it is so fundamental to digital logic.

Declarations of the wires:

wire pex_tx_en;
wire opf_VFSM_mt;


1st:

     if(~pex_tx_en & opf_VFSM_mt) begin
state <= IDLE;
end


2nd:

     if(~pex_tx_en && opf_VFSM_mt) begin
state <= IDLE;
end

• @toolic Thanks, added that in there. I can see how that would definitely affect it. Do you think the synthesis tool would certainly check for that though? Sep 8, 2022 at 18:14
• How is a logical AND different than a bitwise AND? Sep 8, 2022 at 18:25
• @MissMulan logical AND evaluates if a statement on either side of the && symbol is true or false. if both are true the result of the operator will be a 1. If false it will be a 0. Bitwise AND is evaluated bit by bit so if the signals were more than 1 bit wide, bit 0 of the left side would be ANDed (en.wikipedia.org/wiki/AND_gate) with bit 0 of the right side. This would be done for every bit. If the result is greater than 0 then the if statement would be evaluated as if the inside were true. Sep 8, 2022 at 18:36
• No distinction for a single bit signal. But as a coding guideline, if it's gonna be h used as a condition check, you would rather use && than &. So that the intention is clear. Sep 8, 2022 at 19:42

The operator && implies a test-for-nonzero across each variable’s bit-field, followed by the logical AND. It would be the same as applying unary (reduction) OR to each variable then ANDing the two results.

More about Verilog unary operators here: https://verilogcodes.blogspot.com/2015/10/unary-or-reduction-operators-in-verilog.html

Since the variables being tested in your snippets are each one bit wide, the unary OR reduction operators will be optimized away, leaving just the two 1-bit wires ANDed together, so therefore would be synthesized the same as the & (bitwise) operator of two 1-bit vectors.

However, mixing the two paradigms (bitwise in place of logical or vice-versa) is bad coding style. It’s a way that subtle bugs can creep into your code and should be avoided.

If you are expressing logic, better to use the && form even if it seems redundant. Then it’s clear you’re working a Boolean equation and not masking a variable.

On the other hand, by using & (bitwise) only when doing masking calls attention to the fact that you are in fact doing masking, and mean it. When you see that & paradigm, you should be especially alert to check the vector sizes and their alignments on either side of it.

As a sanity check you’d inspect your code searching each operator type (logical &&, bitwise &) and so check for mismatches and unwanted side-effects.

Yes, those two code snippets should infer the same logic in synthesis. Synthesis tools should treat the bitwise and logical AND operators the same in this case. The simulator will behave the same for both snippets as well.

Since you declared the signals as 1-bit wide, the operators will be treated the same. It could get more complicated I suppose if the signals were mutli-bit.

For the particular expression used in your example, there is no difference in the behavior of the two expressions. All synthesis tools should produce the exact same results.

However, for more complex expressions, the are a significant number of other differences between the two operators

• Precedence — the relative operator ordering from highest to lowest is ~, &, ^, |, &&, ||. That means

A ^ B && C ^ D

gets evaluated as

(A ^ B) && (C ^ D)

and

A ^ B & C ^ D

gets evaluated as

A ^ (B & C) ^ D

• Operand and result context — Each operand of && is self-determined. The LHS and RHS get evaluated independently for truth; a zero or non-zero value. The result of the && operator is always a single bit: 1'b1 if both sides are non-zero, 1'b0 if one or both sides are zero. Each operand of the & is context-determined. the smaller width operand gets extended to the larger width operand and the result has the same width as the larger operand. If you had the expression

~A & B

where A has the value 1'b1 and B has the value 2'b11, A would first get extended to 2'b01, then its negation is 2'b10. The result would be 2'b10.

• Short circuiting — If you have A && myFunc(B) and A is zero, myFunc does not get called. If you have A & myFunc(B) and A is zero, myFunc always gets called.

• Im curious how you can be confident that synthesis tools will produce the same results. This case is simple so its more understandable. Also now that I am thinking about it, RTL viewers could be used to verify. In more complex situations is viewing the RTL the only way to tell the synthesis tools had the same result? Sep 20, 2022 at 13:50
• @igrok, because the laws behind Boolean algebra are fixed. There are formal tools that can proof results are equivalent. Sep 20, 2022 at 18:06

There is a simple difference between two operators which will require different synthesis (and simulation) approach

1. 4'b0101 && 4'b1010 ==> 1'b1 --> logically true
2. 4'b0101 & 4'b1010 ==> 4'b0000 --> logically false
• OP’s code is using two 1-bit vectors, so your example does not apply. Sep 11, 2022 at 4:10