Ternary operator vs if else

Can anyone help me out explaining the basic difference between ternary operator (:?) / conditional and if-else conditions?

When I evaluate for x and z values in the condition, the behaviour is unusual in ternary operator. When it incurs x or z for evaluation, it evaluated both true and false conditions and results in an unknown value (x), as it holds 2 mutually exclusive values at the same time step.

Whereas its not the same in if-else, which evaluates as expected sticking to one condition as per its definition.

My sample code :

module ternary_test;

logic [1:0] x;
logic ternary_out,ifelse_out;

function func(int m, string msg);
	if (m) begin
		$display($time,"\tFalse\t%s",msg);
		func = 1;
	end
	else begin
		$display($time,"\tTrue\t%s",msg);
		func = 0;
	end
endfunction

initial ternary_out = (x ==? 2'b0?) ? func(0,"ternary call") : func(1,"ternary call");

initial begin
	if(x ==? 2'b0?)
		ifelse_out = func(0,"ifelse call");
	else
		ifelse_out = func(1,"ifelse call");
end

initial $monitor($time,"\tternary_out = %d\t ifelse_out = %d",ternary_out,ifelse_out);

initial x = 2'b0x;

endmodule : ternary_test

Output :

0 True ternary call

0 False ternary call

0 False ifelse call

0 ternary_out = x ifelse_out = 1

And please do let me know why is this unusual behaviour of ternary operator?

Thanks

Manjush

In reply to manjush_pv:

The behavior of the ternary operator was an attempt to be more realistic in the propagation of unknowns during simulation.

With the ternary operator, it is easy to define its evaluation behavior since the true and false branches must produce a result with the same type. An if/else statement is more general; the code in the true and false branches do not even have to be related to each other. The branches could event have different blocking delays.

In reply to dave_59:

So, ternary operators are synthesizable with more realistic behaviour as on RTL. And how about if-else in this situation, is it synthesizable??

In reply to manjush_pv:

Synthesis tools do not care nor deal with the propagation of unknown values. In your example, both synthesize to the same logic equations.

In reply to dave_59:

Thank you for your explanation

Hi Dave,

if question is modified to something like this:
logic ternary_out;
logic x=x;
initial ternary_out = (x) ? 1 :0 );

then ternary_out=x??

In reply to to_learn_uvm:

I assume you meant to ask:

logic ternary_out;
logic x=1'bx;
initial ternary_out = (x) ? 1 :0 );

then the result of ternary_out will be 1’bx??

That is correct

In reply to dave_59:

To make it more General
ternary_out = (x) ? a :b );

ternary_out[n] will be as follows: where n is the bit index

0 if both a[n] and b[n] are 0
1 if both a[n] and b[n] are 1
x if a[n] and b[n] are different
x if a[n] and b[n] are x or z

Example

module tb;
  
    logic [7:0]  ternary_out;
    logic        c;
    logic [7:0]  a,b; 
  
	initial begin
      
      a = 8'b10101100; 
	  b = 8'b11xx1z01;
      c=1'bx;
      
      ternary_out = (c ? a :b );
      $display("ternary_out = %08b", ternary_out);
    end
endmodule

output
ternary_out = 1xxx1x0x