My answer to What are the common sources of "x" in simulations for an SOC/ASIC design?
Answer by Ramdas Mozhikunnath:
X represents an unknown/indeterminate/dont care value and is only present in simulation and does not represent a real value in silicon.
It is a way in which a simulator tells that it cannot predict if the value will be a 0 or a 1 in real silicon
This can happen for several reasons and here are few:
1. Uninitialized 4 state variables (e.g logic variable in SV): If you declare a variable or net to be a logic type and if it is not initialized , it will have an initial value of X.
2.Uninitialized registers(flip-flops), latches or memories: Because of above reason, if a register/latch is not initialized during reset, it will start of with X. Same goes with memory contents.
3. Signals crossing from a power domain to another power domain and if the source domain is powered off: With multiple power domains and signal crossing these domains, if the source domain is powered off, the outputs are unknown. If there is not proper isolators on signals crossing between power domains, this can cause X propagation to other domain.
4. Multiple drivers on a same net with conflicting values: Verilog/SystemVerilog net types (same as wires) can have multiple drivers and resolve based on the resolving function. Some times if the driving values are conflicting (e.g – one driver driving “0” while another driving “1”), the resulting value can be unknown or X
5. Explicit assignment of “X” values in RTL or driving “X” from testbenches: In some cases, RTL might explicitly have assignment of “X” values to some nets/variables. For e.g: if say some of the case statement leg is not possible, there might be an explicit assignment of “X” as default statement which should never happen and if a bug happens, it can be caught easily. Same can happen if a testbench intentionally wants to test certain conditions by driving “x” ( For e.g: most of data/address bus would be driven X by default except in cycles when an associated “valid” signal is driven)
6. Out of range bit selects and array indexes: If because of some bug, an array or a bit vector is indexed using a select bit which is out of range, the resultant value would be X.
Two good references that I found worth reading are following. These also explain bugs that can get masked because in some cases simulator treats “X” to be more optimistic and how to code to make some of the “X” issues to be more pessimistic.
2. A good 3 part article –