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.
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
This is a short-hand to avoid writing and missing out on a long sensitivity list.
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.
* 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
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.
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