As others mentioned/explained, undefined behavior is not the same as 'randomness'. And I believe you misunderstood the meaning of always @(*)
construct in your example code.
Simulator perspective
First of all, it doesn't mean that randomly flip the value of tempBit
. It means that: 'Simulator may trigger this always
block for any changes in the values (i.e., events) of signals which are used as input within this always
block.
This is a short-hand to avoid writing and missing out on a long sensitivity list.
The signal tempBit
is used as input, so any changes in tempBit
will trigger the always
block. But again, since the change in tempBit
will cause a change to itself due to the feedback, and always
block keeps on triggering, and never stabilizes to a value which simulator can resolve for that simulation-time interval. So this is undefined behavior for an RTL simulator to simulate.
Synthesiser perspective
Secondly, *
has nothing to do with Synthesiser, because Synthesisers ignore the sensitivity list ahead of implementation on an FPGA/ASIC. What is taken into account by Synthesiser is the piece of description inside the always @(*)
.
tempBit <= ~tempBit ;
You are in summary asking Synthesiser to feedback the output of an inverter to its input (Like a Ring Oscillator). This is a classic example of a combinational loop, which has to be avoided in RTL designs.
A Solution
If you really want to generate psuedo-random (Why not true-random?!) values on FPGA on-board, you might want to take a look at LFSRs on FPGA.
For e.g,: generate a pseudo-random N-bit number, \$ X \$, and assign one of its bits as output to tempBit
, or you may even generate another pseudo-random number \$Y\$ and then assign\$X [Y]\$ to tempBit
.