45

What is the difference between:

if (dataoutput[7:0] == 8'bx) begin

and

if (dataoutput[7:0] === 8'bx) begin 

After executing dataoutput = 52'bx, the second gives 1, but the first gives 0. Why? (0 or 1 is the comparison result.)

0

5 Answers 5

46

Some data types in Verilog, such as reg, are 4-state. This means that each bit can be one of 4 values: 0,1,x,z.

With the "case equality" operator, ===, x's are compared, and the result is 1.

With ==, the result of the comparison is not 0, as you stated; rather, the result is x, according to the IEEE Std (1800-2009), section 11.4.5 "Equality operators":

For the logical equality and logical inequality operators (== and !=), if, due to unknown or high-impedance bits in the operands, the relation is ambiguous, then the result shall be a 1-bit unknown value (x).

Sign up to request clarification or add additional context in comments.

Comments

24

In Verilog:

  • == tests logical equality (tests for 1 and 0, all other will result in x)
  • === tests 4-state logical equality (tests for 1, 0, z and x)

Comments

10

== For comparing bits (0 or 1) === For comparing all 4 states (0, 1, x, z)

== can be synthesized into a hardware (x-nor gate), but === can't be synthesized as x is not a valid logic level in digital, it is infact having voltages in between 0 and 1. And z is not itself any logic, it shows disconnection of the circuit.

2 Comments

X is an unknown state... what is the state of an un-reset flipflop on powerup? X. It could be 0 or 1 in reality. Z is an unknown voltage / floating state, like what you get when there's no outputs attached to the net.
Importantly the reality is that 'X' or undetermined is 1 or 0 in synthesis. Ie, we don't know what it is, but it is concrete and not the actual 'X'. So you can not actually test for 'X' in synthesis. Four value logic is valuable for reasoning about correctness, but the underlying system is boolean.
1

As many already commented, in case a signal has an X, the "normal" comparison operator can led to unknow states/answers. Therefore, if you are comparing from a RAM that can deliver U or X states and you want to really check a match, then you should use the "===" and "!==" operators.

See picture from the systemverilog reference documentation. Snapshot of systemverilog reference

Comments

0

I would add some guidance on use (which other answers don't give; actually, Karan Shah did try to address this).

Review: What is four value?

  • 0 - logic low
  • 1 - logic high
  • X - unspecified/undetermined
  • Z - high Z (or not driven)

We normally like to operate in the domain of the first two.

For simulation, you can intentionally set values to the 'X' state. Such values do not exist in synthesis. The use of !== and === in simulation test is excellent as it will take care of these values. Intentionally forcing test inputs to 'x' when they should be ignored, due to bus signalling, can allow a 'black box' tests to see if any output also become 'x'.

However, most logic for synthesis is internal and doesn't use high Z values. An 'X' value cannot occur during synthesis; although it can be an unknown 0/1 value (at least for FPGA synthesis). So, for synthesis, it is better to opt for == and != in the majority of the cases.


The gtkwave tool kit has an 'lxt2miner' program which can be used to look for 'X' simulation signals beyond the reset cycle. I have a build rule as such,

$(CHECK_DEFINED) : %.check : %.lxt
        $(INFO) ------- Mining $^ ----------
        $(Q)lxt2miner $^ -c 2> /dev/null | grep x$$ | grep '^#[^0]' || true

So, values can be undetermined at t=0 when the reset is applied, but should not occur past that. Of course you can also add checks for 'z' and 'x' by using these operators in a test harness.

1 Comment

=== may synthesize, but is better not to use it when synthesizing.